2009-02-16 77 views
17

我們已經看到我是如何NInject can do itAutoFac can do it試圖找出如何使用溫莎城堡如何使用溫莎依賴注入ActionFilterAttributes

目前我使用的是一個醜陋的靜態到依賴注入MVC​​ ActionFilters IoC的輔助類來解決從構造函數代碼依賴這樣的:

public class MyFilterAttribute : ActionFilterAttribute 
{  
    private readonly IUserRepository _userRepository; 
    public MyFilterAttribute() : this(IoC.Resolve<IUserRepository>()) { } 
    public MyFilterAttribute(IUserRepository userRepository) 
    { 
    _userRepository = userRepository; 
    } 
} 

我很想從我的過濾器去除靜態反模式的IoC的事情。

任何暗示,我會如何去做與溫莎城堡?

而且,不改變DI框架不是一種選擇。

回答

10

做一個通用屬性:MyFilterAttribute與男星拍攝類型作爲參數 - 即是這樣的:

public class MyFilterAttribute : ActionFilterAttribute { 
    public MyFilterAttribute(Type serviceType) { 
     this.serviceType = serviceType; 
    } 

    public override void OnActionExecuting(FilterExecutingContext c) { 
     Container.Resolve<IFilterService>(serviceType).OnActionExecuting(c); 
     // alternatively swap c with some context defined by you 
    } 

    // (...) action executed implemented analogously 

    public Type ServiceType { get { return serviceType; } } 
    public IWindsorContainer Container { set; get; } 
} 

然後用同樣的方法,你指的是兩篇文章,以便採取的控制如何調用動作,以及將WindsorContainer手動注入到屬性中。

用法: [MyFilter(typeof運算(IMyFilterService))]

那麼你實際的過濾器將在實施IMyFilterService類這反過來應該實現IFilterService這可能是這個樣子:

public interface IFilterService { 
    void ActionExecuting(ActionExecutingContext c); 
    void ActionExecuted(ActionExecutedContext c); 
} 

這樣你的過濾器甚至不會綁定到ASP.NET MVC,而你的屬性僅僅是一段元數據 - 它實際上應該是這樣的! :-)

+2

我同意:屬性不應該是「可執行的」,而只是一個標籤。 – 2009-02-16 23:24:53

+2

非常感謝您的回答!我運行了幾個mods:1)Container.Resolve行需要一個通用參數。我改變它使用Container.Resolve(serviceType)並將其轉換。 2)我繼承了mvccontrib WindsorControllerFactory並在CreateController()中添加了ActionInvoker。 – 2009-02-17 08:23:59