Dependency Injection是什麼?

Z-xuan Hong
5 min readMay 2, 2020

--

參考書籍

Dependency Injection、Inversion of Control、Dependency Inversion Principle這幾個名詞聽的霧煞煞,大家知道其中的關連嗎?

先來看看各個名詞的定義:

Dependency Injection:傳統產生物件時,物件會自己產生自己需要的dependency,而DI則是產生物件時,此物件需要的dependency需由Client端提供,像是注入一樣(因此稱之為依賴注入)。

Inversion of Control:傳統使用函式庫時,我們都會直接呼叫函式庫的功能,我們掌握程式的主控制流程,但在IoC裡,我們沒有控制主程式流程的權利,而必須實作對方要求的介面,而對方會在他們定義的流程中呼叫你實作的物件,像是.Net MVC、Spring MVC這類型的框架都是IoC的精神,也就是著名的Hollywood principle: Don’t call us, we call you

Dependency Inversion Principle:Program應該要依賴於抽象化介面,而不是實作細節,介面的功能應該以Client端的觀點定義(Client需要哪些功能),如此一來雖然在Run-time時是Client端依賴Concrete Instance,但Compile Structure卻是Concrete Instance依賴抽象化而Client端也依賴抽象化,達到反轉的效果。

講了這麼多,而DI到底是什麼?而DI、DIP、IoC到底有什麼關聯?

DI:一系列的Pattern與Principle讓我們可以開發出低耦合的軟體,耦合性越低,越能簡單的修改特定的模組,讓軟體更好維護,更好修改。

一切都是為了讓軟體更好維護,更好修改,讓軟體變軟!讓我們更能擁抱改變!

  1. 而為了要低耦合,我們必須要依賴抽象化,不要依賴細節(DIP)
  2. 即便是抽象化,我們仍然需要產生Concrete Instance,因此我們讓Client端提供Concrete Instance而不是物件自己產生(DI)
  3. 以第二點的方式遞迴直到程式進入點(Entry Point),此時所有物件都只依賴於抽象化。
  4. 因此物件的產生會集中在同一個地方,DI稱之為Composition Root,此時所有物件放棄控制dependency的生命週期,進而由Composition Root控制物件的生命週期(IoC)

當我們放棄物件控制生命週期時會發生一些有趣的事情:

  1. Object Composition集中在Composition Root
  2. Object LifeCycle Mangement集中在Composition Root
  3. Object Intercept集中在Composition Root

如此一來我們可以:

  1. 輕鬆的組裝不同物件。
  2. 輕鬆的控制物件生命週期(因此也不需要Singleton Design Pattern幫我們控制單一物件生成)。
  3. 輕鬆針對抽象化去Decorate不同的責任來達到SRP(Intercept:中文為截擊,攔截之意,攔截特定的抽象化,並且動態新增責任到他們身上)。

看到這時,你可能會想有了DI,那DI Container呢?這不重要嗎?

沒錯!DI Container在DI裡面扮演的角色是相對次要的!因此不需要DI Container也能達到DI的手段(又稱之為PoorMan’s DI)

DI Container做的事情就是:

  1. 幫助更簡單組織複雜的物件。
  2. 幫助你控制複雜物件的生命週期。
  3. 幫助你針對抽象化去Decorate不同的責任(Intercept)。

而這些事情都只會發生在Composition Root(Entry Point)。

所以也就有Dependency Injection三大概念的產生:

  • Object Composition
  • Object Lifetime Management
  • Object Interception(Cross-Cutting-Concern)

到了這邊,希望能讓你對Dependency Injection有更深層的了解,之後系列文章會以程式碼範例去解釋DI,今天則介紹DI的基本原則。

附上StackOverFlow的經典問題:

How to explain dependency injection to a 5-year-old?

When you go and get things out of the refrigerator for yourself, you can cause problems. You might leave the door open, you might get something Mommy or Daddy doesn’t want you to have. You might even be looking for something we don’t even have or which has expired.

What you should be doing is stating a need, “I need something to drink with lunch,” and then we will make sure you have something when you sit down to eat.

結論:有時學會放棄,會得到意想不到的收穫。

--

--

Z-xuan Hong
Z-xuan Hong

Written by Z-xuan Hong

熱愛軟體開發、物件導向、自動化測試、框架設計,擅長透過軟工幫助企業達到成本最小化、價值最大化。單元測試企業內訓、導入請私訊信箱:t107598042@ntut.org.tw。

No responses yet