一. 什么是IoC
當(dāng)在A類中要使用B類的時(shí)候,我們一般都是采用new的方式來實(shí)例化B類,這樣一來這兩個(gè)類就有很強(qiáng)的依賴關(guān)系,不符合低耦合的設(shè)計(jì)思想。這時(shí)候我們可以
通過一個(gè)中間容器來實(shí)例化對(duì)象
,需要的時(shí)候就可以通過容器獲取一個(gè)B類的對(duì)象。這種思想就是IoC(控制反轉(zhuǎn)),其實(shí)我覺得叫控制轉(zhuǎn)移更為合適,因?yàn)樗前殉绦騽?chuàng)建對(duì)象的控制權(quán)轉(zhuǎn)移給了第三方(IoC容器)。
以上是我的個(gè)人見解,如有不對(duì)的地方還望指正,謝謝
二. 代碼實(shí)現(xiàn)IoC思想
首先進(jìn)行分析,因?yàn)槲覀兪峭ㄟ^IoC容器來獲取對(duì)象的,但是IoC容器一開始是不知道我們都需要那些對(duì)象的,這時(shí)候就可以通過配置XML文件來告訴IoC容器。
1.創(chuàng)建控制臺(tái)應(yīng)用程序
2.定義要進(jìn)行實(shí)例化的類
1 public class User 2 { 3 /// <summary> 4 /// 定義一個(gè)方法,打印Hello,用來后期測試 5 ///
</summary> 6 public void SayHello() 7 { 8 Console.WriteLine("Hello"); 9 }
10 } View Code
?
3.定義XML節(jié)點(diǎn)
這里為了方便我直接在App.config配置文件中來定義節(jié)點(diǎn),首先我們需要定制一個(gè)約定來說明節(jié)點(diǎn)和屬性的意義。
<!--以下是我自己定制的一些約定--> <myobjects></myobjects> <!--存放我需要的所有對(duì)象--> <object></object
><!--要實(shí)例化的對(duì)象--> name <!--name屬性來聲明對(duì)象的名字--> type <!--type屬性來聲明對(duì)象的類型--> assembly
<!--assembly屬性來聲明對(duì)象所在的程序集--> View Code
以下是我App.config中的內(nèi)容
?
4.創(chuàng)建IoC容器(最關(guān)鍵的一步)
核心技術(shù)其實(shí)也就是反射編程。
1 public class IoCContainer 2 { 3 //定義一個(gè)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 //獲取項(xiàng)目的根目錄的絕對(duì)路徑 , 21
//因?yàn)闇y試時(shí)應(yīng)用生成在'根目錄/bin/Debug' 所以需要向上走兩個(gè)目錄 22 string rootPath =
Path.GetFullPath(AppDomain.CurrentDomain.BaseDirectory +@"..\..\"); 23 //
加載config文件 24 XElement xElement = XElement.Load(rootPath+"App.config"); 25 //
獲取myobjects節(jié)點(diǎn)下的子集合 26 IEnumerable<XElement> items = xElement.Descendants("
myobjects").Elements(); 27 //循環(huán)實(shí)例化節(jié)點(diǎn) 28 foreach (var item in items) 29 { 30 //
通過反射加載程序集 31 var assembly = Assembly.LoadFrom(item.Attribute("assembly").Value);
32 //創(chuàng)建實(shí)例 33 var entity = assembly.CreateInstance(item.Attribute("type").Value);
34 //添加到容器中 35 Container.Add(item.Attribute("name").Value, entity); 36 } 37 38
}39 }
5.測試&對(duì)比
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 //一般的創(chuàng)建對(duì)象 6
User user =new User(); 7 8 //使用IoC容器獲取對(duì)象 9 var container =
IoCContainer.GetContainer();10 User userIoC = container["UserEntityOne"] as
User;11 12 //測試方法 13 userIoC.SayHello(); 14 Console.ReadKey(); 15 } 16 }
?
運(yùn)行項(xiàng)目,確實(shí)是輸出了"Hello",證明使用IoC容器創(chuàng)建對(duì)象是成功了。
三. 總結(jié)
通過創(chuàng)建對(duì)象的方式明顯可以感覺到耦合度降低了,我們將耦合的代碼移到XML文件中,通過容器來管理對(duì)象的依賴關(guān)系,如果說有什么變動(dòng)的話只需要改XML中的配置即可,而不用重新編譯。關(guān)于性能我沒有去測試,可想而知肯定沒用直接new性能高,但
只要將其思想在項(xiàng)目中用到合適的地方,我相信利是遠(yuǎn)遠(yuǎn)大于弊的。
?
(如有不對(duì)的地方請(qǐng)指正,萬分感謝)
熱門工具 換一換