Зарегистрировать глобальные фильтры в ASP.Net MVC 4 и Autofac

У меня есть такой фильтр:

public class CustomFilterAttribute : ActionFilterAttribute, IAuthorizationFilter
{
    public MyPropery Property { get; set; }
    ....
}

Мне нужно, чтобы он запускался для каждого действия в моем проекте

Я попытался зарегистрировать его в GlobalFilters, но мое свойство не вводится

пробовал данное решение чтобы зарегистрировать мой фильтр, но он не называется

есть идеи, как это сделать?

2 ответов


существует новый способ регистрации глобальных фильтров MVC в AutoFac. Во-первых, удалить Регистрация фильтра от вашего RegisterGlobalFilters потому что у нас будет ручка Autofac, добавляющая их в наши контроллеры / действия вместо MVC.

затем зарегистрируйте свой контейнер следующим образом:

var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());

builder.RegisterType<MyProperty>().As<IProperty>();

builder.Register(c => new CustomFilterAttribute(c.Resolve<IProperty>()))
                .AsActionFilterFor<Controller>().InstancePerHttpRequest();

builder.RegisterFilterProvider();

IContainer container = builder.Build();

DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

обратите внимание, что, передав в Controller класс в расширение AsActionFilterFor() мы говорим AutoFac применить этот фильтр ко всем классам, производным от Controller класс (который, в MVC, является всеми контроллерами). Так как мы зовем AsActionFilterFor() без каких-либо аргументов мы также указываем, что хотим, чтобы фильтр применялся ко всем действиям в указанных контроллерах. Если вы хотите применить фильтр к контроллеру select и действию, вы можете использовать лямбда-выражения, такие как:

builder.Register(c => new CustomFilterAttribute(c.Resolve<IProperty>()))
    .AsActionFilterFor<HomeController>(c => c.Index())
    .InstancePerHttpRequest();

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

builder.Register(c => new CustomFilterAttribute(c.Resolve<IProperty>()))
    .AsActionFilterFor<HomeController>(c => c.Detail(default(int)))
    .InstancePerRequest();

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

  • AsActionFilterFor
  • AsAuthorizationFilterFor
  • AsExceptionFilterFor
  • AsResultFilterFor

Теперь вы должны использовать решение Пита, чтобы сделать это. Спасибо ему за обновленное решение.

я, наконец, сделал это, вот как это делается:

сначала создайте свой атрибут с помощью конструктора со всеми зависимостями

public class CustomFilterAttribute : ActionFilterAttribute, IAuthorizationFilter
{
    private IProperty _property;

    public CustomFilterAttribute(IProperty repository)
    {
        _property = property;
    }
    ....
 }

зарегистрировать все, что вам нужно в autofac

var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());

builder.RegisterType<MyProperty>().As<IProperty>();
builder.RegisterType<CustomFilterAttribute>().SingleInstance();

builder.RegisterFilterProvider();

IContainer container = builder.Build();

DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

зарегистрируйте свой глобальный фильтр так

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    filters.Add(DependencyResolver.Current.GetService<CustomFilterAttribute>());
}

убедитесь, что в вашей глобальной.asax вы регистрируете сначала Autofac, а затем global фильтры.

Теперь вам больше не нужна инъекция свойств, инъекция конструктора будет работать нормально, что хорошо!