3

我已經使用StructureMap超過一年了。而這一切的時候,我曾經有過所謂的IoC的包裝類,它看起來像這樣是否爲您的IoC包裝了一個好主意?

class IoC { 
    public static T GetInstance<T>() 
    { 
     return (T)GetInstance(typeof(T)); 
    } 
    public static IEnumerable<T> GetAllInstances<T>() 
    { 
     return ObjectFactory.GetAllInstances<T>(); 
    } 

    public static IEnumerable GetAllInstances(Type type) 
    { 
     return ObjectFactory.GetAllInstances(type); 
    } 

    public static object GetInstance(Type type) 
    { 
     return ObjectFactory.GetInstance(type); 
    } 

    public static void Inject<T>(T obj) 
    { 
     ObjectFactory.Inject(obj); 
    } 
} 

我加了包裝假設我可能要在某些時候的路線改變IoC容器。在這一點上,我認爲這是不好的。一個原因是:我不能在我的代碼中使用ObjectFactory來做其他有趣的事情,我必須使用這個包裝器。另一件事是:我們的代碼不應該獨立於DependencyInjection容器。

使用這種方法的優點/缺點是什麼?

+0

[Mark Seemann](http://blog.ploeh.dk/)稱這種包裝爲'符合容器'。他最近寫了一篇關於此的博客文章(http://blog.ploeh。dk/2014/05/19/conforming-container /),他明確地稱這是一種反模式。 – Steven 2014-06-21 14:12:09

回答

6

出於這個原因,Common Service Locator項目已經研製成功。它是DI框架的一個抽象概念,它定義了一個非常類似於您的IoC類的接口。我甚至開發了Simple Service Locator庫;一個直接實現Common Service Locator接口的DI庫。

因此從這個意義上說,對DI框架進行抽象並不奇怪。然而,當正確(完全)執行依賴注入時,其思想是相應地調整應用程序的設計,將容器配置在應用程序根目錄中,並且最好只在應用程序中的一個位置組裝類型(讀取:分別爲GetInstance被稱爲)。對於ASP.NET MVC應用程序,這將是ControllerFactory。對於ASP.NET WebForms應用程序,通常需要覆蓋PageHandlerFactory

當你通過這些規則行事,沒有理由用這樣一個抽象的,因爲你只需要調用的容器中,在應用程序中的一個地方呢。但是,如果這對您不可行,則可以使用Common Service Locator或您自己的抽象。

但是請您退後一步,然後再決定是否讓您的代碼依賴於您的IoC庫的抽象,因爲這會導致很多問題,並且一般會導致is seen as an anti-pattern。從代碼中調回容器:

  • 使代碼難以測試。
  • 隱藏依賴關係,而不是使代碼難以閱讀和維護。
  • 禁用編譯時支持。
  • 不允許使用工具驗證依賴關係圖。
+0

使用外部依賴關係的包裝是有意義的,但是,我不知道是否有任何人們切換其IoC容器的真實情況。 – 2010-11-25 05:56:13

1

親是你可以無痛切換IOC容器。這意味着你失去了特定於IOC容器的任何功能。 MVC渦輪機使用這種方法。看看它是如何處理定位器的。 http://mvcturbine.codeplex.com/

1

如果你有很多庫和建立在這些庫之上的很多應用程序,那麼最終會得到大量的IoC註冊碼,這些註冊碼會在所有這些應用程序中重複使用。

你可以讓每個庫負責註冊一個容器,但它必須知道具體的IoC實現。或者你可以按照你的建議來做,並創建一個IoC包裝器,讓你的庫負責通過IoC包裝器註冊自己。

相關問題