爲了更好地理解依賴注入的概念,首先了解一下軟件設計模式是頗有必要的。軟件設計模式主要用來規範問題及其解決方案的描述,以簡化開發人員對常見問題及其對應解決方案的標識與交流。設計模式
幾乎每一個人都看過或是本身寫過下面代碼的經歷服務器
1 public class EmailService 2 { 3 public void SendMsg() 4 { 5 Console.WriteLine("Hello world !!!"); 6 } 7 } 8 9 /// <summary> 10 /// 耦合實現 11 /// </summary> 12 public class NotificationSys 13 { 14 private EmailService svc; 15 16 public NotificationSys() 17 { 18 svc = new EmailService(); 19 } 20 21 public void InterestingEventHappened() 22 { 23 svc.SendMsg(); 24 } 25 }
上述代碼中,NotificationSys 類依賴EmailService類,當一個組件依賴其餘組件稱之耦合。在軟件設計過程,高耦合一般認爲是軟件設計的責任。當一個類精確地知道另外一個類的設計和實現時,就會增長軟件修改的負擔,由於修改一個類頗有可能破壞依賴它的另外一個類。爲下降組件之間的耦合程序,通常採起兩個獨立但相關的步驟:app
1.在兩塊代碼之間引入抽象層,因此上述代碼可修改成如下ide
1 public interface IEmailService 2 { 3 void SendMsg(); 4 } 5 public class EmailService : IEmailService 6 { 7 public void SendMsg() 8 { 9 Console.WriteLine("Hello world !!!"); 10 } 11 } 12 /// <summary> 13 /// 抽象接口來實現 14 /// (把抽象實現的責任移到消費者的外部) 15 /// </summary> 16 public class NotificationSys1 17 { 18 private IEmailService svc; 19 public NotificationSys1() 20 { 21 svc = new EmailService1(); 22 } 23 public void InterestingEventHappened() 24 { 25 svc.SendMsg(); 26 } 27 }
2.把選擇抽象實現的責任移到消費者類的外部。函數
控制反轉(IOC)模式是抽象的;把依賴的建立移到使用這些的類的外部,這稱爲控制反轉模式,之因此以這樣命名,是由於反轉的是依賴的建立,正由於如此,才消除消費類對依賴建立的控制。ui
依賴注入是另外一種控制反轉模式形式,它沒有像服務器定位器同樣的中間對象。相反,組件以一種容許依賴的方式編寫,一般由構造函數參數或屬性設置器來顯式表示。
spa
1. 構造函數注入設計
DI 的最多見形式是構造函數注入。該技術須要咱們爲類建立一個顯示錶示因此依賴的構造函數。3d
1 /// <summary> 2 /// 構造注入 3 /// </summary> 4 public class NotificationSys 5 { 6 private IEmailService _svc; 7 8 public NotificationSys(IEmailService svc) 9 { 10 _svc =svc ; 11 } 12 public void InterestingEventHappened() 13 { 14 _svc.SendMsg(); 15 } 16 }
優勢: 極大簡化構造函數的實現;減小了NotificationSys類須要知道的信息量;需求的透明性,任何想建立NotificationSys類實例的代碼都能查看構造函數,並精確的知道哪些內容是消費者必須的。rest
2.屬性注入
屬性注入是一種不太常見的依賴注入方式。顧名思義,該方式是經過設置對象上公共屬性而不是經過使用構造函數參數來注入依賴。
public class NotificationSys { private IEmailService svc{get;set;} public void InterestingEventHappened() { svc.SendMsg(); } }
顯而易見,這裏咱們已經減小了需求的透明性,並且絕對比構造函數注入更容易產生錯誤。
選擇屬性注入緣由:
若是依賴在某種意義上是真正可選的,即在消費者類不提供依賴時,也有相應的處理,屬性注入是個不錯的選擇
類的實例可能須要在咱們尚未控制調用的構造函數的狀況下被建立
依賴注入容器是一個能夠做爲組件工廠使用的軟件庫,它能夠自動檢測和知足裏面元素的依賴需求。常見的DI容器有 CastleWindsor,Unity,Autofac, ObjectBuilder,StructureMap,Spring.Net
路漫漫其修遠兮, 吾將上下而求索