2012-11-12 92 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