Подтвердить что ты не робот

Как использовать Windsor для встраивания зависимостей в ActionFilterAttributes

Увидев, как NInject может это сделать и AutoFac может это сделать Я пытаюсь выяснить, как вводить зависимости в MVC 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 из моих фильтров.

Любые намеки на то, как я буду делать это с Castle Windsor?

И нет, изменение рамки DI не является вариантом.

4b9b3361

Ответ 1

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

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, а ваш атрибут - всего лишь часть метаданных - так, как это должно быть!: -)