一. 什麼是IoC 當在A類中要使用B類的時候,我們一般都是採用new的方式來實例化B類,這樣一來這兩個類就有很強的依賴關係,不符合低耦合的設計思想。這時候我們可以通過一個中間容器來實例化對象,需要的時候就可以通過容器獲取一個B類的對象。這種思想就是IoC(控制反轉),其實我覺得叫控制轉移更為合適, ...
一. 什麼是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性能高,但只要將其思想在項目中用到合適的地方,我相信利是遠遠大於弊的。
(如有不對的地方請指正,萬分感謝)