31

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

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

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

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

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

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

4

2 回答 2

47

有一种在 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));

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

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
于 2014-02-03T19:17:02.437 回答
17

您现在应该使用 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,然后再注册全局过滤器。

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

于 2012-11-12T17:07:01.070 回答