2010-11-12 103 views
13

我有一個從AuthorizationAttribute派生的自定義屬性類,它對控制器操作執行自定義安全性。 OnAuthorizationCore方法依賴於各種其他組件(例如DAL),以判斷用戶是否可以調用某個操作。如何解決MVC中的依賴注入過濾器屬性

我正在使用Autofac進行依賴注入。 ExtensibleActionInvoker聲稱能夠在動作過濾器上執行屬性注入。在運行時設置一個屬性的屬性(這看起來是一個壞主意)可以在一個簡單的單元測試中工作,但是在一個繁忙的多線程Web服務器中,它肯定會出錯,所以這個想法看起來像是反模式。因此,這個問題:

如果我的AuthorizationAttribute依賴於其他組件,以便正確工作,它是什麼權利[體系結構]模式,以實現這一目標?

即AuthorizationAttribute取決於IUserRepository ...如何應該這種關係得到解決?

回答

17

ExtensibleActionInvoker聲稱能夠在動作過濾器上執行屬性注入。

正確 - 但不要將操作篩選器與可能無法實現它們的屬性混淆。用ASP解決這個問題的最簡單的方法。即使MVC框架允許您將它們組合起來,.NET MVC也將分擔責任。

例如,使用一對類 - 只保存數據的屬性類:

// Just a regular old attribute with data values 
class SomeAttribute : Attribute { ... } 

和具有相關性的過濾器注入:

// Gets dependencies injected 
class SomeFilter : IActionFilter { ... } 

SomeFilter只使用獲得的典型方法來自控制器的SomeAttribute屬性或通過GetCustomAttributes()的操作方法來做任何需要的工作。

然後可以使用ExtensibleActionInvoker要連接過濾器:

builder.RegisterControllers(...).InjectActionInvoker(); 
builder.RegisterType<ExtensibleActionInvoker>().As<IActionInvoker>(); 
builder.RegisterType<SomeFilter>().As<IActionFilter>(); 

這可能是一個多一點的代碼比你寫的使用屬性作爲過濾器的方法,但代碼的質量將從長遠來看會更好(例如,通過避免屬性的侷限性和服務定位器解決方案的尷尬)。

+0

謝謝尼克 - 他們都是一個徹底的答案和一個精彩的框架! – Mark 2010-11-15 07:10:20

2

在MVC2之前沒有直接的做法。這裏有一個有趣的技術:http://www.mattlong.com.au/?p=154。我建議使用Common Service Locator對此進行抽象並找到您的DI容器。

如果你使用MVC 3,那麼你可以使用MVC Service Location

+2

無論如何,使用CSL如果是服務定位器,那麼使用CSL有什麼意義?當你知道你的代碼將被其他可能更喜歡另一個容器的人重新使用時,通常會使用CSL。不要認爲有抽象的理由。 – 2010-11-12 13:41:07

+0

那個人被認爲是死亡 - 它總是歸結爲一種意識形態的觀點, – 2010-11-12 13:50:25

2

我看來,實現這一目標的最簡單方法是硬着頭皮接受autofac本身的依賴。雖然對IoC的依賴本身就是一種反模式,但它更具吸引力。你可以實現一個屬性如下:

public class UserAuthorizeAttribute : AuthorizeAttribute 
{    
    public IUserRepository CurrentUserService 
    { 
     get 
     { 
      var cpa = (IContainerProviderAccessor)HttpContext.Current.ApplicationInstance; 
      var cp = cpa.ContainerProvider; 
      return cp.RequestLifetime.Resolve<IUserRepository>(); 
     } 
    } 
} 
    ... 
0

構造函數注入似乎是不可能不改變過濾器註冊的方式。

即使in Asp.Net Mvc3

一個地方依賴注入已經很難在過去是內部的過濾器屬性本身。因爲.NET框架運行時實際上負責創建這些屬性實例,所以我們不能使用傳統的依賴注入策略。

所以 - 接下來最好的事情是屬性注入(Mvc3提供了一些開箱即用的支持)。

這是手動完成此操作的how to

我個人使用MvcExtensions。我很好,在different way註冊他們。這裏是usage

您可能想要調查的另一件事是MvcTurbine項目。與更通用的MvcExtensions項目相比 - MvcTurbine主要用於提供依賴注入支持。