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

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

У меня есть фильтр, подобный этому:

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

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

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

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

Любая идея о том, как это сделать?

4b9b3361

Ответ 1

Появился новый способ регистрации глобальных фильтров 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() без каких-либо аргументов, мы также указываем, что хотим, чтобы фильтр применялся ко всем действиям в указанных контроллерах. Если вы хотите применить свой фильтр к выбранному контроллеру и действию, вы можете использовать лямбда-выражения так:

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

Ответ 2

Теперь вы должны использовать решение Pete для этого. Благодаря ему за обновленное решение.

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

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

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>());
}

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

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