2011-12-05 32 views
17

我看到領導開發人員編寫這樣的代碼,並在閱讀馬克·席曼的書「依賴注入.NET」我想知道如果具體的「新」是「外國」,因此「混蛋注入」?這是「混蛋注入反模式」的好例子嗎?

public class SessionInitServiceManager 
{ 
    protected readonly ICESTraceManager _traceManager; 
    protected readonly ILogger _logger; 
    protected readonly IAggregateCalls _aggregator; 
    protected readonly IMultiCoreRepository _repository; 

    public SessionInitServiceManager(ICESTraceManager traceManager, 
            ILogger logger, 
            IAggregateCalls aggregator, 
            IMultiCoreRepository repository) 
    { 
     _traceManager = traceManager; 
     _logger = logger; 
     _aggregator = aggregator; 
     _repository = repository; 
    } 

    public SessionInitServiceManager() : this(new CESTraceManager(), 
               new Logger("BusinessServices.authenticateUser"), 
               new Aggregator(), 
               new RepositoryFactory().BuildMultiCoreRepository()) { } 
+0

順便說一句,四個參數被推向極限明智的DI(作者指出,他的限制通常是4),因爲它迫使你開始質疑SessionInitServiceManager是否違反SRP。傳遞另一個經理類也表明這可能是這樣的。 – RichK

+0

是的,我記得讀到3-4是一般的限制,如何避免這個新問題的例子有或沒有像IOC容器一樣? –

+4

答案取決於是否任何'默認'實現定義在同一個庫或不同的libr元。 http://stackoverflow.com/questions/6733667/is-there-an-alternative-to-bastard-injection-aka-poor-mans-injection-via-defa/6739953#6739953 –

回答

9

這當然看起來像Bastard Injection的典型例子。原因是因爲你有四個外部默認值。 Foreign Default指的是默認值,其中類型來自不同的模塊/項目/ DLL。我會將丙基包括在這個定義中的命名空間,因爲命名空間可以表示在將來的點你可以進入自己的模塊的界限。當你決定使用本地默認值時(這樣我將來把它分解成它自己的模塊嗎?),這更多的是關於這個問題。

這將不是Bastard注射的方式將是所有這些類生活在同一模塊。造成這種情況非常糟糕的一個原因是因爲你拖動了依賴關係,現在你的類與這些類緊密相連。如果我選擇使用我自己的日誌記錄版本,那麼我必須帶着DLL進行日誌記錄等等,儘管我沒有使用它,但是否定了模塊化應用程序設計的好處。

+0

這聽起來對我很好。謝謝! –

0

我碰巧從朋友那裏借用了.NET中的依賴注入書。我明白你在說什麼。我確實相信這是「混蛋注射」。這是一個殘酷的術語,但我認爲畢竟ColdFusion(咳嗽)具有「CFABORT」標籤作爲該語言的一部分。

此外,我注意到一篇好文章,博文How not to do dependency injection - the static or singleton container

基本上,我們開始之前,讓我們得到的東西的方式:

依賴注入=使用IoC容器「

這裏是踢球,」這是靜態的容器的誕生。除了更改控制器採取依賴關係的構造,我們只是改變這裏的服務被實例化使用容器它,而不是解決就行了。」

public class HomeController 
{ 
    private readonly IExampleService _service; 

    public HomeController() 
    { 
     _service = Container.Instance.Resolve<IExampleService>(); 
    } 

    public ActionResult Index() 
    { 
     return View(_service.GetSomething()); 
    } 
} 
+3

在實際使用Service Locator反模式的默認構造函數中,您如何知道容器將爲您提供IExampleService?如果它不?在Index方法中NullArgumentException,並且在設計時它看起來「很好」。這不是使用IoC容器,這是以錯誤的方式應用DI –