国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

認(rèn)識(shí)IoC

2019-11-17 03:08:29
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

認(rèn)識(shí)IoC

  第一次接觸IoC是我在學(xué)習(xí)MVP框架的時(shí)候,搭建一個(gè)MVP框架需要用到IoC,那時(shí)候就以為IoC就是依賴(lài)注入,但在后來(lái)的逐步了解中發(fā)現(xiàn)那個(gè)只是它的別名而已。IoC全稱(chēng)應(yīng)該是Inversion of Control,中文稱(chēng)為控制反轉(zhuǎn);而依賴(lài)注入的簡(jiǎn)稱(chēng)是DI,全稱(chēng)是Dependency Injection,個(gè)人覺(jué)得這兩者也不是那么一個(gè)別名的關(guān)系而已,控制反轉(zhuǎn)給我的感覺(jué)更多的是一種思想,而依賴(lài)注入?yún)s正好是一種實(shí)現(xiàn)方式。那這里說(shuō)說(shuō)概念

  • 控制反轉(zhuǎn):應(yīng)用本身不負(fù)責(zé)以來(lái)對(duì)象的維護(hù)和創(chuàng)建,而交給一個(gè)外部容器來(lái)負(fù)責(zé)。這樣控制權(quán)就由應(yīng)用轉(zhuǎn)到了外部IoC容器,控制權(quán)就實(shí)現(xiàn)了所謂的反轉(zhuǎn)。
  • 依賴(lài)注入:由外部容器在運(yùn)行時(shí)動(dòng)態(tài)地將以來(lái)的對(duì)象注入到組件中。

以上概念摘自蔣老師的著作《asp.net MVC4 框架揭秘》。但是技術(shù)這東西又沒(méi)必要向理論學(xué)術(shù)那樣嚴(yán)謹(jǐn),能讓人知曉其中意圖則可,最初UML最初創(chuàng)作處理也是為了達(dá)到這個(gè)目的。

  高內(nèi)聚低耦合一直是軟件開(kāi)發(fā)中不斷追求的,現(xiàn)在各種框架MVC,MVP等都是為了解耦而誕生的。在我閱讀微軟的開(kāi)源項(xiàng)目PetShop時(shí)發(fā)現(xiàn)里面用了耳熟能詳?shù)娜龑蛹軜?gòu)中使用了最初我學(xué)C#時(shí)不知有什么作用的一個(gè)東西——接口Interface。它的存在很大的目的就是為了解耦,它能使一些比較具體的事物抽象化。那么本篇所討論的IoC也是使用了接口。

目前有很多IoC框架:Unity,SPRing.NeT,Ninject,StructureMap等。Ninject在我實(shí)踐MVP的時(shí)候用過(guò),Unity在我閱讀蔣老師的著作時(shí)了解過(guò),那么這回我將會(huì)嘗試一下之前沒(méi)用過(guò)的Unity,體驗(yàn)一下依賴(lài)注入。

模擬使用一個(gè)三層架構(gòu)來(lái)體驗(yàn)這個(gè)Unity

定義DAL,BLL,UI層的接口IDAL,IBLL,IUI以及實(shí)現(xiàn)它們的類(lèi)DAL,BLL,UI。

 1     interface IDAL 2     { 3         DataTable QueryDatas(); 4     } 5     interface IBLL 6     { 7         List<object> GetSomeDatas(); 8     } 9 10     interface IUI11     {12         void ShowData(IBLL bll);13     }14 15     class DAL : IDAL16     {17 18         public DataTable QueryDatas()19         {20             DataTable table = new DataTable();21             table.Columns.Add("Col");22             for (int i = 0; i < 10; i++)23             {24                 table.Rows.Add(i);25             }26             return table;27         }28     }29     class BLL : IBLL30     {31         [Dependency]32         public IDAL dal { get; set; }33 34         public List<object> GetSomeDatas()35         {36             List<object> result = new List<object>();37             DataTable table = dal.QueryDatas();38             foreach (DataRow row in table.Rows)39             {40                 result.Add(row[0]);41             }42             return result;43         }44     }45     class UI : IUI46     {47         [InjectionMethod]48         public void ShowData(IBLL bll)49         {50             List<object> datas = bll.GetSomeDatas();51             foreach (object item in datas)52             {53                 Console.WriteLine(item);54             }55         }56     }

在上面的代碼中BLL類(lèi)的dal屬性使用了[Dependency] Attribute,使得該屬性是通過(guò)IoC容器自動(dòng)去賦值,不需要通過(guò)代碼給它顯示賦值。UI的ShowData方法用了[InjectionMethod] Attribute,該方法在UI類(lèi)被IoC容器自動(dòng)執(zhí)行。實(shí)際上上面代碼設(shè)計(jì)到IoC里面三種方式的其中兩種屬性注入和接口(方法)注入,那么還剩下一種就是構(gòu)造器注入,

  • 在上面使用了Dependency Attribute的IDAL屬性則是使用屬性注入,使用了依賴(lài)注入的屬性在IoC容器構(gòu)造對(duì)象的時(shí)候自動(dòng)初始化賦值;
  • 上面使用了InjectionMethod Attribute的ShowData方法則是使用接口(方法)注入,使用了依賴(lài)注入的方法在IoC容器構(gòu)造對(duì)象的時(shí)候自動(dòng)執(zhí)行該方法;
  • 還有一種沒(méi)有列舉出來(lái)的就是構(gòu)造器注入, IoC容器會(huì)自動(dòng)選擇和調(diào)用合適的構(gòu)造函數(shù)以創(chuàng)建依賴(lài)的對(duì)象。如果被選擇的構(gòu)造函數(shù)是帶參數(shù)的,IoC容器是會(huì)去創(chuàng)建該參數(shù)的實(shí)例的。上面的代碼還沒(méi)可以執(zhí)行,需要在配置文件中添加以下內(nèi)容
 1 <configuration> 2   <configSections> 3     <section name="unity" 4              type=" 5              Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, 6              Microsoft.Practices.Unity.Configuration"/> 7   </configSections> 8   <unity> 9     <containers>10       <container name="defaultContainer">11         <register type="AllTypeTestControl.IDAL,AllTypeTestControl" mapTo="AllTypeTestControl.DAL,AllTypeTestControl"/>12         <register type="AllTypeTestControl.IBLL,AllTypeTestControl" mapTo="AllTypeTestControl.BLL,AllTypeTestControl"/>13         <register type="AllTypeTestControl.IUI,AllTypeTestControl" mapTo="AllTypeTestControl.UI,AllTypeTestControl"/>14       </container>15     </containers>16   </unity>17 </configuration>

上面這段內(nèi)容是指定了給Unity的IoC容器各個(gè)接口與實(shí)現(xiàn)類(lèi)的映射關(guān)系,AllTypeTestControl.IDAL類(lèi)型映射到AllTypeTestControl.DAL中去,表示通過(guò)DAL來(lái)實(shí)現(xiàn)IDAL的注入,其他同理。但每一項(xiàng)的注冊(cè)要按照

<register type="接口全名,程序集名" mapTo="類(lèi)全名,程序集名"/>

通過(guò)下面的測(cè)試代碼來(lái)測(cè)試

1         public static void TestMain()2         {3             IUnityContainer container = new UnityContainer();4             UnityConfigurationSection configuration = 5                 ConfigurationManager.GetSection(UnityConfigurationSection.SectionName) 6                 as UnityConfigurationSection;7             configuration.Configure(container, "defaultContainer");8             UI ui = container.Resolve<IUI>() as UI ;9         }

主要是構(gòu)造了一個(gè)IoC的容器,然后載入了配置文件的映射信息,除了通過(guò)配置文件來(lái)確定映射關(guān)系外,還可以通過(guò)代碼的形式來(lái)確定

        public static void TestMain()        {            IUnityContainer container = new UnityContainer();            container.RegisterType<IDAL, DAL>();            container.RegisterType<IBLL, BLL>();            container.RegisterType<IUI, UI>();            UI ui = container.Resolve<IUI>() as UI ;        }

代碼的運(yùn)行結(jié)果如下

現(xiàn)在則把上面的BLL作一下修改

 1     class BLL : IBLL 2     { 3         //[Dependency] 4         //public IDAL dal { get; set; } 5  6         private IDAL dal; 7  8         //[InjectionConstructor] 9         public BLL(IDAL dal)10         {11             this.dal = dal;12         }13 14         //[InjectionConstructor]15         public BLL()16         { 17         18         }19 20         public List<object> GetSomeDatas()21         {22             List<object> result = new List<object>();23             DataTable table = dal.QueryDatas();24             foreach (DataRow row in table.Rows)25             {26                 result.Add(row[0]);27             }28             return result;29         }30     }

結(jié)果仍然和上面的一樣,IoC容器仍然能正確的匹配出類(lèi)型構(gòu)造了DAL對(duì)象。那么如果給BLL()構(gòu)造函數(shù)加了InjectionConstructor Attribute,IoC容器只會(huì)去匹對(duì)帶了InjectionConstructor Attribute的構(gòu)造函數(shù),這樣BLL(IDAL dal)構(gòu)造函數(shù)則不會(huì)被調(diào)用,運(yùn)行起來(lái)就會(huì)拋出空引用異常。假如給BLL(IDAL dal)也加上了InjectionConstructor Attribute,那么它與無(wú)參構(gòu)造函數(shù)BLL()屬于同級(jí),IoC則會(huì)也調(diào)用BLL(IDAL dal)構(gòu)造函數(shù),dal字段能被正常的賦值。

  通過(guò)上面的實(shí)踐中能感覺(jué)到IoC有GOF中的工廠模式思想。用戶(hù)在使用著一個(gè)對(duì)象,但它并不負(fù)責(zé)對(duì)象的構(gòu)造,把對(duì)象的構(gòu)造移交了給第三方,在IoC中就是IoC容器,在工廠方法里面則是工廠了。在ASP.NET MVC中也使用了IoC,迷你MVC框架中控制器的構(gòu)造是通過(guò)了一個(gè)工廠利用反射機(jī)制來(lái)構(gòu)造出來(lái)的,而實(shí)際的ASP.NET MVC則是使用了IoC。

  對(duì)IoC的了解還不算多,手上有一份Ninject的源碼,但一直沒(méi)看,現(xiàn)在工作忙了,連博客也少寫(xiě)了,時(shí)間得好好分配,要保持學(xué)習(xí)。以上有什么說(shuō)的不對(duì)的請(qǐng)指正,有什么好的建議或意見(jiàn)也請(qǐng)分享,謝謝!


發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 西乌珠穆沁旗| 湘乡市| 兴安盟| 车险| 梅州市| 新绛县| 济宁市| 葫芦岛市| 通渭县| 广宗县| 吉木萨尔县| 绥化市| 万宁市| 汉阴县| 九寨沟县| 韶关市| 札达县| 永顺县| 绥德县| 大安市| 潜山县| 德令哈市| 廊坊市| 额济纳旗| 曲松县| 涞源县| 安国市| 彰化市| 龙州县| 沁阳市| 奉化市| 柏乡县| 昌宁县| 鄂托克前旗| 宁德市| 安陆市| 瓮安县| 扶绥县| 民县| 黎城县| 平遥县|