1

我遇到了像Ninject,Unity或其他任何類型的IoC(DI)容器的優點。我理解如下概念:DI容器的好處和正確用法

  • DI:將依賴關係注入需要它的類(最好通過構造函數注入)。我完全明白爲什麼不太緊密的耦合是一件好事。

    public MyClass{ 
        ISomeService svc; 
    
        public MyClass(ISomeService svc){ 
         svc = svc; 
        } 
    
        public doSomething(){ 
         svc.doSomething(); 
        } 
    } 
    
  • 服務定位器:當一個「容器」被直接使用,需要一個扶養類內部,解決了扶養。我確實得到了這樣的觀點,即產生了另一個依賴關係,我也看到基本沒有任何東西被注入。現在

    public MyClass{     
        public MyClass(){} 
    
        public doSomething(){ 
         ServiceLocator.resolve<ISomeService>().doSomething(); 
        } 
    } 
    

,什麼混淆我是一個 「DI容器」 的概念。對我來說,它看起來就像一個服務定位器,根據我的理解,它只應用於應用程序的入口點/啓動方法,以註冊並解決依賴關係,並將它們注入其他類的構造函數中 - 而不是這需要扶養(可能是爲什麼服務定位器被認爲是「壞」同樣的道理)

  • 什麼是使用容器時,我可以創建扶養,並把它傳遞到目的的具體類中構造函數?

    public void main(){     
        DIContainer.register<ISomeService>(new SomeService()); 
        // ... 
    
        var myclass = new MyClass(DIContainer.resolve<ISomeService>()); 
        myclass.doSomething(); 
    } 
    
  • 是否真的有意義通過所有的依賴關係的所有類的應用程序初始化方法?可能有100個最終需要(或不需要)的依賴關係,並且僅僅因爲它被認爲是您在init方法中創建它們的良好實踐?

+1

這是一篇關於使用容器的優點和缺點的優秀文章:http://blog.ploeh.dk/2012/11/06/WhentouseaDIContainer/ – jrahhali

回答

2

什麼是使用容器時,我可以創建扶養並將它傳遞給構造函數的目的是什麼?

DI容器應該可以幫助您快速創建對象圖形。你只需告訴它哪個具體的實現你想用於哪個抽象(註冊階段),然後它可以創建任何你想要的對象(解析階段)。

如果您創建依賴關係並將它們傳遞給構造函數(在應用程序初始化代碼中),那麼您實際上正在執行Pure DI

我認爲在很多情況下Pure DI是一種更好的方法。查看我的文章here

將應用程序初始化方法中的所有依賴項都傳遞給所有類是否真的有意義?可能有100個最終需要(或不需要)的依賴關係,並且僅僅因爲它被認爲是您在init方法中創建它們的良好實踐?

我會說是。您應該在應用程序啓動時創建對象圖。這被稱爲composition root

如果您需要在應用程序啓動後創建對象,那麼您應該使用factories(主要是抽象工廠)。而這樣的工廠將與其他對象一起創建。

你的類在構造函數中不應該做太多的工作,這會使創建所有依賴項的成本變得很低。

但是,我想說在特殊情況下使用new關鍵字創建某些類型的對象是可以的。就像對象是簡單的一樣Data Transfer Object (DTO)