2015-12-02 76 views
0

我有一個ASP.NET MVC 5應用程序,我使用Structuremap 3作爲IOC。Structuremap 3單接口多種類型

我有一個通過N層使用多種類型的接口,我無法找到如何將多種類型映射到自動構造函數注入的相同接口的簡潔說明。

比如我在註冊表中的以下聲明

For<IDataContextAsync>().Use<DbGeoContext>(); 
For<IDataContextAsync>().Use<DbEspContext>(); 

當我跑我的應用我理解IDataContextAsync的最後添加的實例將使用的默認實例時,我的應用程序創建一個類的實例需要一個IDataContextAsync作爲構造函數中的參數。

所以我的問題是我如何告訴Structuremap 3在註冊表中使用與正在創建的類型相關的IDataContextAsync的特定實例?

謝謝。

回答

0

爲了區分不同的實現,可以使用命名實例(請參閱文檔here)。您註冊一個命名實例是這樣的:

//Default instance 
For<IDataContextAsync>().Use<DbGeoContext>(); 
For<IDataContextAsync>().Add<DbEspContext>().Named("EspContext"); 

注意,Add方法,無需將其設置爲默認註冊了一個實例,而Use方法它註冊爲默認實例。正如您已經意識到的那樣,使用Use方法註冊的最後一個實例成爲默認實例。

爲了判斷哪些實例應該傳遞給構造一個dependee,您可以使用Ctor指令指定構造函數的參數(見文檔here):

For<IMyRepository>().Use<MyRepository>() 
    .Ctor<IDataContextAsync>().Named("EspContext"); 

這是一個容易混淆的命名簡寫:

For<IMyRepository>().Use<MyRepository>() 
    .Ctor<IDataContextAsync>() 
    .Is(c => c.GetInstance<IDataContextAsync>("EspContext")); 

或者,你可以跳過指定的參數魔法,只是直行的具體類型有:

For<IMyRepository>().Use<MyRepository>() 
    .Ctor<IDataContextAsync>().Is<DbEspContext>(); 
+0

嗨,謝謝你的回覆,最終我發現了它,但是我花了一段時間。我會標記你的答案,但我還沒有足夠的分數。 – Csharper

+0

其實我在應用程序啓動時發現了一個問題,我檢索EspContext的實例並更新它的連接字符串,但是當我將請求追蹤到存儲庫層時,連接字符串沒有改變?嗯...是否有另一種方法比GetInstance將做同樣的事情,但沒有創建一個實例? – Csharper

+0

從一開始就將連接字符串設置爲正確的值不是更容易嗎?如果直到應用程序生命週期中的某個特定時間點才知道該值,請使用工廠模式並注入一個可生成連接的工廠,而不是注入實際連接。我認爲你的問題是,它與你更改的版本庫不同。您可以爲結構圖中的每種類型設置[生命週期](http://structuremap.github.io/object-lifecycle/supported-lifecycles/)。默認值爲transient(每個對象圖的新對象)。 – PHeiberg