Мне нравится этот код, потому что вы не связываете сервисный локатор с MyAuthorizeAttribute.

астройки. Скажем, у меня есть фильтр действий, которому нужен экземпляр службы:

public interface IMyService
{
   void DoSomething();
}

public class MyService : IMyService
{
   public void DoSomething(){}
}

Затем у меня есть ActionFilter, которому нужен экземпляр этой службы:

public class MyActionFilter : ActionFilterAttribute
{
   private IMyService _myService; // <--- How do we get this injected

   public override void OnActionExecuting(ActionExecutingContext filterContext)
   {
       _myService.DoSomething();
       base.OnActionExecuting(filterContext);
   }
}

В MVC 1/2 введение зависимостей в фильтры действий было чем-то вроде боли в заднице. Наиболее распространенный подход заключался в том, чтобы использовать средство вызова пользовательских действий, как можно увидеть здесь:http://www.jeremyskinner.co.uk/2008/11/08/dependency-injection-with-aspnet-mvc-action-filters/ Основная мотивация этого обходного пути заключалась в том, что следующий подход считался небрежным и тесно связанным с контейнером:

public class MyActionFilter : ActionFilterAttribute
{
   private IMyService _myService;

   public MyActionFilter()
      :this(MyStaticKernel.Get<IMyService>()) //using Ninject, but would apply to any container
   {

   }

   public MyActionFilter(IMyService myService)
   {
      _myService = myService;
   }

   public override void OnActionExecuting(ActionExecutingContext filterContext)
   {
       _myService.DoSomething();
       base.OnActionExecuting(filterContext);
   }
}

Здесь мы используем инжектор конструктора и перегружаем конструктор, чтобы использовать контейнер и внедрить сервис. Я согласен, что это тесно связывает контейнер с ActionFilter.

Мой вопрос, однако, заключается в следующем: теперь в ASP.NET MVC 3, где у нас есть абстракция используемого контейнера (через DependencyResolver), все эти обручи все еще необходимы? Позвольте мне продемонстрировать:

public class MyActionFilter : ActionFilterAttribute
{
   private IMyService _myService;

   public MyActionFilter()
      :this(DependencyResolver.Current.GetService(typeof(IMyService)) as IMyService)
   {

   }

   public MyActionFilter(IMyService myService)
   {
      _myService = myService;
   }

   public override void OnActionExecuting(ActionExecutingContext filterContext)
   {
       _myService.DoSomething();
       base.OnActionExecuting(filterContext);
   }
}

Теперь я знаю, что некоторые пуристы могут насмехаться над этим, но серьезно, что может быть недостатком? Он все еще тестируемый, так как вы можете использовать конструктор, который берет IMyService во время тестирования и таким образом внедрить фиктивный сервис. Вы не привязаны к какой-либо реализации контейнера DI, так как используете DependencyResolver, поэтому есть ли недостатки этого подхода?

Кстати, вот еще один хороший подход для этого в MVC3 с использованием нового интерфейса IFilterProvider:http://www.thecodinghumanist.com/blog/archives/2011/1/27/structuremap-action-filters-and-dependency-injection-in-asp-net-mvc-3

Ответы на вопрос(3)

Ваш ответ на вопрос