Как использовать Windsor для внедрения зависимостей в ActionFilterAttributes - PullRequest
17 голосов
/ 16 февраля 2009

Посмотрев, как NInject может это сделать и AutoFac может это сделать Я пытаюсь выяснить, как внедрить зависимости в MVF ActionFilters, используя Castle Windsor

В настоящее время я использую уродливый статический вспомогательный класс IoC для разрешения зависимостей из кода конструктора, например:

public class MyFilterAttribute : ActionFilterAttribute
{    
  private readonly IUserRepository _userRepository;
  public MyFilterAttribute() : this(IoC.Resolve<IUserRepository>()) { }
  public MyFilterAttribute(IUserRepository userRepository)
  {
     _userRepository = userRepository;
  }
}

Я бы хотел удалить статический антипаттерн IoC из моих фильтров.

Любые намеки на то, как мне поступить с Касл Виндзор?

И нет, изменение структуры DI невозможно.

Ответы [ 2 ]

18 голосов
/ 06 ноября 2009

Когда мне это понадобилось, я опирался на работу, которую другие проделали с Ninject и Windsor, чтобы получить зависимости внедрения свойств от моих ActionFilters .

10 голосов
/ 16 февраля 2009

Создайте общий атрибут: MyFilterAttribute, где ctor принимает аргумент Type в качестве аргумента, т.е. что-то вроде этого:

public class MyFilterAttribute : ActionFilterAttribute {
    public MyFilterAttribute(Type serviceType) {
        this.serviceType = serviceType;
    }

    public override void OnActionExecuting(FilterExecutingContext c) {
        Container.Resolve<IFilterService>(serviceType).OnActionExecuting(c);
        // alternatively swap c with some context defined by you
    }

    // (...) action executed implemented analogously

    public Type ServiceType { get { return serviceType; } }
    public IWindsorContainer Container { set; get; }
}

Затем используйте тот же подход, что и две статьи, на которые вы ссылаетесь, чтобы взять под контроль то, как вызываются действия, и выполнить ручную инъекцию вашего WindsorContainer в атрибут.

Использование: [MyFilter (TypeOf (IMyFilterService))]

Тогда ваш действительный фильтр будет в классе, реализующем IMyFilterService, который, в свою очередь, должен реализовать IFilterService, который может выглядеть примерно так:

public interface IFilterService {
    void ActionExecuting(ActionExecutingContext c);
    void ActionExecuted(ActionExecutedContext c);
}

Таким образом, ваш фильтр даже не будет привязан к ASP.NET MVC, а ваш атрибут - просто часть метаданных - так, как это и должно быть! : -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...