c#之控制反轉(IOC)和依賴注入(DI)的理解

這兩個東西曾經困擾很多新手朋友,下面就給大家詳細介紹一下!

首先說控制反轉(IOC)

控制反轉不是一種技術,只是一種思想,一個重要的面向對象編程的法則,它能指導我們如何設計出松耦合、更優良的程序。

其實IoC對編程帶來的最大改變不是從代碼上,而是從思想上,發生了“主從換位”的變化。應用程序原本是老大,要獲取什麼資源都是主動出擊自己去找,但是在IoC思想中,應用程序就變成被動的了,被動的等待調用方來創建並注入它所需要的資源了。

簡單的說就是:“別找我們,我們找你”;

下面用一個簡單的例子來講解讓大家更容易理解。

下面是一段演示代碼:


在shop類中, Log4NetServices是一個日誌類,_logServices直通過new Log4NetServices()實例化,日誌記錄會自動保存數據庫中。

現在問題來了,領導要求日誌要到文件中去,兩種解決辦法:

1、修改shop類。

<code>_logServices=new FileLogServices()/<code>

這樣改有下面幾個問題。

1.1、後續如果要改為數據庫保存日誌,又要去改shop類。

1.2、如果有的日誌要保存數據庫,有的日誌要保存在文件,也要修改shop類。

當一個類會出現類似的需求的時候,我們就需要用到這個依賴注入這個思想。就是_logServices由誰來實例化,不要在shop中來定義,而是由調用方來實現。

改進後的代碼如下:


在shop類中,_logServices只是一個ILogServices接口,沒有具體的實現,由調用方來實現。

通過上面改進,就可以實現靈活的擴展,對於不復雜的應用,這種改進已經足夠用了,但是有一天程序越來越龐大,參與的人越來越多的時候,就會出現下面的問題:

1、參與的人多了,每個人調用時候都一個個的new。

2、ILogServices出現更多的實現(如保存成excle,保存為txt,保存到緩存等等),也就是種類多了,調用方需要一個一個的new。

當業務變龐大以後,架構師就要考慮這個問題,能不能new統一起來管理,需要的人統一從一個固定的地方獲取呢?

然後依賴注入框架出現了。

DI依賴注入(Dependency Injection)

網上有很多描述,我自己都看的雲裡霧裡的,最後也不知道說什麼,下面用我的話來總結:

類和類之間依賴關係由容器在運行期決定,形象的說,即由容器動態的將某個依賴關係注入到類之中。依賴注入的目的並非為軟件系統帶來更多功能,而是為了提升組件重用的頻率。

簡單的說就是:“誰依賴誰,為什麼需要依賴,誰注入誰,注入了什麼”

●誰依賴於誰:當然是應用程序依賴於IoC容器;

●為什麼需要依賴:應用程序需要IoC容器來提供對象需要的外部資源;

●誰注入誰:很明顯是IoC容器注入應用程序某個對象,應用程序依賴的對象;

●注入了什麼:就是注入某個對象所需要的外部資源(包括對象、資源、常量數據)。

IoC和DI由什麼關係呢?其實它們是同一個概念的不同角度描述,由於控制反轉概念比較含糊(可能只是理解為容器控制對象這一個層面,很難讓人想到誰來維護對象關係),所以2004年大師級人物Martin Fowler又給出了一個新的名字:“依賴注入”,相對IoC 而言,“依賴注入”明確描述了“被注入對象依賴IoC容器配置依賴對象”。

目前有很多成熟的IOC框架,如unity和Auotfac,這兩個框架網上都有詳細的使用配置教程,這裡就不講解了。因為在在NetCore後,框架已經可通過ServiceProvider類和ServiceCollection類實現依賴注入,代碼如下:

總結

使用IoC對於複雜的項目來說,非常有意義,能夠為我們搭建一個好的開發層次。