2012-11-12 91 views
26

注册全局过滤器我有这样一个过滤器:在ASP.Net MVC 4和Autofac

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

我需要为每一个动作在我的项目上运行

我试图将其注册在GlobalFilters但我的财产不会被注入

我试图This solution登记自己的过滤器,但它不会被调用

如何做到这一点任何想法?

回答

40

有一种在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
+1

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

15

您现在应该使用皮特的解决方案来做到这一点。感谢他提供了一个更新的解决方案。

我终于成功了,这里是如何做到这一点:

首先创建一个构造函数的属性,具有所有依赖性

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,然后是全局过滤器。

现在,您不再需要属性注入了,构造函数注入将很好地工作,这是一件好事!

+0

你是如何获取这是需要调用在Global.asax中的静态方法GlobalFilterCollection滤波器参数?我可以忽略一些东西吗 –

+0

没关系,我在Application Start方法中看到了FilterConfig.RegisterGlobalFilters。 –

+5

如果您需要您的依赖关系范围为每个请求,则这不起作用。 – ischell