34

我正在爲ASP.Net MVC網站創建自定義成員提供程序。提供者被創建爲一個獨立的類作爲更大的庫的一部分。後端數據存儲需要靈活,因爲它可能是Xml文件或SQL數據庫。我最初的想法是爲數據存儲創建一個接口,並使用依賴注入將其注入提供程序。依賴注入和ASP.Net成員提供程序

是必需的最終結果是,開發者可以繼承數據存儲接口,並提供所需要的方法來更新數據,其然後由自定義的成員資格提供使用。

但是,通過我自己的技能匱乏,我無法弄清楚如何將其添加到會員供應商的類時,將其添加到網站?需要做些什麼來將數據存儲鏈接到提供者?在網站中啓用此功能最簡單的方法是什麼?

+0

你熟悉的任何依賴注入的框架? – Restuta

+0

@Restuta - 不,我不是在尋找一個框架。一個簡單的界面就足以滿足這個特定的要求。開發人員應該能夠通過簡單地繼承接口來創建自己的後端存儲。 – BinaryMisfit

+1

我認爲框架可以爲您節省很多時間。它將用於注入特定的實現到你自定義的Membership Provider中,這個任務是最複雜的,因爲你無法控制提供者的初始化。 – Restuta

回答

31

如果您通過在Web.config文件中的成員<>元素配置自定義的成員提供者,那麼我可以看到你將有依賴注入的問題。

提供程序由框架構建和管理,並且您沒有機會截取該構造以爲IDataStore接口提供額外的依賴注入。

如果我的假設是正確的,那麼你可以做的是覆蓋在你的自定義提供了Initialize()方法,並做了依賴注入那裏。您可以在提供程序配置中具有自定義名稱/值設置,該設置指向實現IDataStore的類型,該類型作爲字典的一部分傳遞給Initialize()方法。

然後,激活數據存儲類型的實例,並設置相應的屬性:它構造你的供應商的實例後

public class MyMembershipProvider : MembershipProvider 
{ 
    public IDataStore DataStore 
    { 
     get; 
     set; 
    } 

    public override Initialize(string name, NameValueCollection config) 
    { 
     var dataStoreType = config["dataStoreProvider"]; 
     if (!String.IsNullOrEmpty(dataStoreType)) 
     { 
      var type = Type.GetType(dataStoreType); 
      DataStore = (IDataStore) Activator.CreateInstance(type); 
     } 
    } 
} 

Initialize()將被框架調用,所以這是完美的地方做任何額外的設置工作,如這樣。

在測試環境下,您只需設置上提供實例本身數據存儲屬性,你會在你的測試直接構建它。

+1

完美。我正在尋找的代碼。謝謝! – BinaryMisfit

+0

有以類似的方式完成修復這裏找到:http://bugsquash.blogspot.com.au/2010/11/windsor-managed-membershipproviders.html它基本上實現了裝飾設計模式來包裝由創建的實例你DI容器。 –

+0

這不再適用於.Net 4.6.2 – IronSean

2

做的依賴注入,我已經看到了(實際上是唯一一個至今我用...)最簡單的方法是讓你依賴的類的構造函數把接口作爲參數,並分配它到一個私人領域。如果你願意,你還可以添加一個「默認」構造函數,該函數鏈接到第一個具有默認值的構造函數。

簡化,它會是這個樣子:

public class DependentClass 
{ 
    private IDataStore _store; 

    // Use this constructor when you want strict control of the implementation 
    public DependentClass(IDataStore store) 
    { 
     this._store = store; 
    } 

    // Use this constructor when you don't want to create an IDataStore instance 
    // manually every time you create a DependentClass instance 
    public DependentClass() : this(new DefaultDataStore()) { } 
} 

這個概念被稱爲「構造函數鏈」,並有很多關於如何做它在網絡上的文章。我發現this tutorial非常解釋了DI模式。

+0

謝謝。我經常使用DI,所以我對這部分非常舒服。我的問題是特定於在web.config中配置的成員資格提供程序。山姆的解決方案解決了這個問題。 – BinaryMisfit

+0

@Sleeper:他說他是一個使用ASP.NET MVC,這意味着*是*可以通過集裝箱來解決類。我建議他應該。順便說一句,你不必尖叫。 –

20

這不是更好嗎?我用它與MVC3和ninject。向您的自定義成員資格提供程序類添加屬性就足夠了。請記得添加「使用System.Web.Mvc;」在上面。

public IRepository Repository 
{ 
    get 
    { 
     return DependencyResolver.Current.GetService<IRepository>(); 
    } 
} 
+0

可能。我有一段時間沒有看到這個問題,當時問到的問題仍然是MVC 1.0 – BinaryMisfit

+1

它適用於我。缺點是它是「服務定位器」反模式的一種變體,但有時您必須對架構做出妥協。 (見http://stackoverflow.com/questions/22795459/is-servicelocator-anti-pattern)。我不知道他們是不是應該在ASP.NET vNext來解決這個問題,但希望。 –