我的認知
先來段情境,當 A 類別依賴一個 B 物件時,也就是A類別裡有段 code 為
var b= new B();
// todo
如果有天需求從 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 的 Nuget 套件供參考:
1. Unity(範例使用)
2. Autofac
若是 .Net Core 就用內建的 DI 去實現。
若想知道更多請參考下篇「相依性注入(DI/IoC範例)」