名詞
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範例)」