C#程式碼實現IoC(控制反轉)設計,以及我對IoC的理解
阿新 • • 發佈:2019-08-29
一. 什麼是IoC
當在A類中要使用B類的時候,我們一般都是採用new的方式來例項化B類,這樣一來這兩個類就有很強的依賴關係,不符合低耦合的設計思想。這時候我們可以通過一箇中間容器來例項化物件,需要的時候就可以通過容器獲取一個B類的物件。這種思想就是IoC(控制反轉),其實我覺得叫控制轉移更為合適,因為它是把程式建立物件的控制權轉移給了第三方(IoC容器)。 以上是我的個人見解,如有不對的地方還望指正,謝謝二. 程式碼實現IoC思想
首先進行分析,因為我們是通過IoC容器來獲取物件的,但是IoC容器一開始是不知道我們都需要那些物件的,這時候就可以通過配置XML檔案來告訴IoC容器。
1.建立控制檯應用程式
2.定義要進行例項化的類
1 public class User 2 { 3 /// <summary> 4 /// 定義一個方法,列印Hello,用來後期測試 5 /// </summary> 6 public void SayHello() 7 { 8 Console.WriteLine("Hello"); 9 } 10 }View Code
3.定義XML節點
這裡為了方便我直接在App.config配置檔案中來定義節點,首先我們需要定製一個約定來說明節點和屬性的意義。
<!--以下是我自己定製的一些約定--> <myobjects></myobjects> <!--存放我需要的所有物件--> <object></object><!--要例項化的物件--> name <!--name屬性來宣告物件的名字--> type <!--type屬性來宣告物件的型別--> assembly <!--assembly屬性來宣告物件所在的程式集-->View Code
以下是我App.config中的內容
4.建立IoC容器(最關鍵的一步)
核心技術其實也就是反射程式設計。
1 public class IoCContainer 2 { 3 //定義一個Dictionary作為容器 4 private static Dictionary<string, object> Container = new Dictionary<string, object>(); 5 /// <summary> 6 /// 獲取容器 7 /// </summary> 8 /// <returns></returns> 9 public static Dictionary<string, object> GetContainer() 10 { 11 //獲取之前先載入 12 LoadContainer(); 13 return Container; 14 } 15 16 /// <summary> 17 /// 載入填充容器 18 /// </summary> 19 private static void LoadContainer() { 20 //獲取專案的根目錄的絕對路徑 , 21 //因為測試時應用生成在'根目錄/bin/Debug' 所以需要向上走兩個目錄 22 string rootPath = Path.GetFullPath(AppDomain.CurrentDomain.BaseDirectory + @"..\..\"); 23 // 載入config檔案 24 XElement xElement = XElement.Load(rootPath+"App.config"); 25 //獲取myobjects節點下的子集合 26 IEnumerable<XElement> items = xElement.Descendants("myobjects").Elements(); 27 //迴圈例項化節點 28 foreach (var item in items) 29 { 30 //通過反射載入程式集 31 var assembly = Assembly.LoadFrom(item.Attribute("assembly").Value); 32 //建立例項 33 var entity = assembly.CreateInstance(item.Attribute("type").Value); 34 //新增到容器中 35 Container.Add(item.Attribute("name").Value, entity); 36 } 37 38 } 39 }
5.測試&對比
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 //一般的建立物件 6 User user = new User(); 7 8 //使用IoC容器獲取物件 9 var container =IoCContainer.GetContainer(); 10 User userIoC = container["UserEntityOne"] as User; 11 12 //測試方法 13 userIoC.SayHello(); 14 Console.ReadKey(); 15 } 16 }
執行專案,確實是輸出了"Hello",證明使用IoC容器建立物件是成功了。
三. 總結
通過建立物件的方式明顯可以感覺到耦合度降低了,我們將耦合的程式碼移到XML檔案中,通過容器來管理物件的依賴關係,如果說有什麼變動的話只需要改XML中的配置即可,而不用重新編譯。關於效能我沒有去測試,可想而知肯定沒用直接new效能高,但只要將其思想在專案中用到合適的地方,我相信利是遠遠大於弊的。
(如有不對的地方請指正,萬分感