簡體   English   中英

IOC容器的最佳實踐

[英]Best Practices for IOC Container

我正在使用Unity IOC容器,我只是想知道訪問多個類的容器的最佳方法是什么。

每個類都應該有一個IUnityContainer成員,然后通過構造函數傳遞容器嗎? 是否應該有一個帶有IOC容器的單例類?

asp.net開發怎么樣?

有人可以指導我朝正確的方向發展嗎? 謝謝。

恕我直言,不建議將整個容器注入類或具有應用程序范圍的靜態IoC服務定位器。

您希望能夠從類的構造函數中看到(讓我們稱之為Foo),它使用什么樣的服務/對象來完成工作。 這提高了透明度,可測試性和可脫氣性。

讓我們說Foo只需要電子郵件服務,但我傳入整個容器和代碼中的某個地方,電子郵件服務從容器中解析出來。 在這種情況下,將很難遵循。 相反,最好將電子郵件服務直接注入狀態Foo的依賴關系更清晰。

如果Foo需要創建電子郵件服務的多個實例,最好創建並注入一個EmailServiceFactory(通過IoC容器),它將動態創建所需的實例。

在后一種情況下,Foo的依賴關系仍然表示盡可能具體 - 只有EmailServiceFactory可以創建的依賴關系。 如果我注入了整個容器,那就不清楚它提供的服務是Foo的確切依賴。

現在,如果我以后想要提供電子郵件服務的不同實例,我會在EmailServiceFactory中交換它。 如果它所創建的所有服務都需要交換(例如在測試期間),我也可以換掉整個工廠。

因此,以創建一個額外的類(工廠)為代價,我獲得了更清晰的代碼,並且不必擔心使用全局靜態時可能發生的奇怪錯誤。 另外,當提供模擬測試時,我確切地知道它需要什么模擬,而不必模擬整個容器的類型。

這種方法也具有優勢,現在,當模塊初始化時(僅適用於Prism / Modularity),它不必注冊它提供給IoC容器的所有類型的對象。 相反,它只能注冊其ServiceFactory然后提供這些對象。

為了清楚起見,模塊的初始化類(實現IModule)仍應在其構造函數中接收應用程序范圍的IoC容器,以便提供其他模塊使用的服務,但容器不應侵入模塊的類。

最后,我們這里有一個額外的間接層如何解決問題的另一個很好的例子。

將IOC容器放在進程中的最高級別/入口點,並使用它將依賴項注入其下的所有內容。

你可以在容器中注冊容器並像其他依賴屬性一樣注入容器,如下所示:

IUnityContainer container = new UnityContainer();
container.RegisterInstance<IUnityContainer>(container);

需要訪問它的類將具有以下屬性:

private IUnityContainer unityContainer;
[Dependency]
public IUnityContainer UnityContainer
{
    get { return unityContainer; }
    set { unityContainer = value; }
}

因此,只要解決/建立了這種類的實例,就注入容器。

這更靈活,因為它適用於同一應用程序中的多個容器,而使用單例模式是不可能的。

如果所有對象都需要對容器的引用,那么您應該考慮重新編寫代碼。 雖然仍然比在任何地方調用new更好,但它仍然分散了在整個代碼中構建對象圖的責任。 有了這種用法,它更像是一個ServiceLocator而不是IoC Container。

另一種選擇是使用CommonServiceLocator ,雖然它可能是無意義的間接,但您可以使用ServiceLocator.Current作為所有類已知的實例

我在我的博客上有一篇關於這個主題的帖子,我使用了t3mujin答案的內容。 隨意使用它(不要打擾它的相關點...無關緊要):

http://johanleino.spaces.live.com/blog/cns!6BE273C70C45B5D1!213.entry

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM