在ASP.Net MVC 4和Autofac中注册全局过滤器

Swe*_*ell 31 autofac action-filter asp.net-mvc-4 asp.net-mvc-filters

我有一个像这样的过滤器:

public class CustomFilterAttribute : ActionFilterAttribute, IAuthorizationFilter
{
    public MyPropery Property { get; set; }
    ....
}
Run Code Online (Sandbox Code Playgroud)

我需要为项目中的每个动作运行它

我试图在GlobalFilters中注册它,但我的属性没有被注入

我试过这个解决方案来注册我的过滤器,但它没有被调用

有关如何做到这一点的任何想法?

Pet*_*ete 46

有一种在AutoFac中注册MVC全局过滤器的新方法.首先,从您的过滤器注册中删除,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));
Run Code Online (Sandbox Code Playgroud)

请注意,通过将Controller类传入扩展,AsActionFilterFor()我们告诉AutoFac将此过滤器应用于从类派生的所有类Controller(在MVC中,所有类都是控制器).由于我们在AsActionFilterFor()没有任何参数的情况下调用,因此我们还指定我们希望将过滤器应用于指定控制器中的所有操作.如果要将过滤器应用于选择控制器和操作,可以使用lambda表达式,如下所示:

builder.Register(c => new CustomFilterAttribute(c.Resolve<IProperty>()))
    .AsActionFilterFor<HomeController>(c => c.Index())
    .InstancePerHttpRequest();
Run Code Online (Sandbox Code Playgroud)

如果您的操作采用参数,请使用default关键字指定:

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

请注意,您必须根据要注册的过滤器类型使用不同的扩展方法,以下是支持的过滤器类型:

  • AsActionFilterFor
  • AsAuthorizationFilterFor
  • AsExceptionFilterFor
  • AsResultFilterFor

  • 这让我很难受!文档(http://docs.autofac.org/en/latest/integration/mvc.html#enable-property-injection-for-action-filters)仍然提到属性注入,我想这些需要更新. (2认同)

Swe*_*ell 16

您现在应该使用Pete的解决方案来执行此操作.感谢他提供更新的解决方案.

我终于成功了,这是怎么做的:

首先使用包含所有依赖项的构造函数创建属性

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

    public CustomFilterAttribute(IProperty repository)
    {
        _property = property;
    }
    ....
 }
Run Code Online (Sandbox Code Playgroud)

在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));
Run Code Online (Sandbox Code Playgroud)

像这样注册您的全局过滤器

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

确保在global.asax中首先注册Autofac,然后注册全局过滤器.

现在,你不再需要属性注入,构造函数注入将工作正常,这是一件好事!

  • 如果您需要将作用域限定为每个请求,则此方法无效. (6认同)