Dependency Injection and Inversion of Control

Posted by Max Lin on 2021-05-22

名詞

DI:Dependency Injection(依賴注入)
IoC:Inversion of Controll(控制反轉)

情境說明

先來段情境,當 A 類別依賴一個 B 物件時,也就是 A 類別裡有段 code 為:
var b= new B();

但是!
有天需求從 B 替換其他物件呢?又或是 B 物件以後需要一直替換呢?該怎麼辦?

你可能會想:直接改 new 替換物件(); 就好了啊。
對!這也是一種解決方式,但今天可能有 100 個類別都依賴 B,那就要改 100 次!而且改完的部分都要重新測試過才算真的完成。但這樣一來不僅讓程式碼彈性不佳,更導致日後維護成本過高!

各位高高手也可能會想:
那我把所有依賴 B 物件的地方改為一個專門提供此物件的類別,再從類別寫一個方法去回傳 B 物件就可以了啊。

沒錯!

這就是 Inversion of Controll 概念,把原本程式碼有依賴部分的控制權反轉到某個地方(稱為 IoC 容器),讓依賴 B 的部分轉為依賴IoC 容器,請注意下句話,再由 IoC 容器提供B物件來做使用 ,若日後可能需求要替換成 C 或 D 物件呢?不要說 C 或 D 啦,就算改成:
EFGHIJKLMNOPQRSTUVWXYZ 物件還是歐巴馬、陳菊,都不用怕了!
直接用小手在 IoC 容器一改即可替換全部!

那剛提醒需要注意的 「由IoC容器提供B物件來做使用」 ,其實這句描述的行為就叫做 Dependency Injection ,把需要依賴的部分在 IoC 容器裡都配置好,日後當類別要依賴 B 物件時,容器就會「主動」提供配置好的物件給它做使用。
注意!
講到這邊!
.
.
.
.
.
就講完了。
沒錯!概念就是這麼簡單!

圖示:

總結

若要使用 DI/IoC 的時機,就是針對 日後可能要替換的元件 達到依賴注入,使其保留一定的彈性,這樣一來,不僅可以讓程式碼更容易擴充,維護成本也相對變低了,符合 SOLID-OCP ,定義為對開放擴充,對修改封閉,在還沒有 IoC 容器前只要有依賴 B 物件的部分在需要更動時,都要在程式碼修改,那就不符合 OCP 原則了。
這邊提供幾個常用的 .Net Framework 實現 DI/IoC 的套件供參考:

  • Unity(範例使用)
  • Autofac

若是 .Net Core 就用內建的 DI 去實現。
實作請參考下篇 「相依性注入(DI/IoC範例)」