《電子技術(shù)應(yīng)用》
您所在的位置:首頁(yè) > 嵌入式技術(shù) > 設(shè)計(jì)應(yīng)用 > IoC模式及其應(yīng)用
IoC模式及其應(yīng)用
2016年微型機(jī)與應(yīng)用第06期
(沙洲職業(yè)工學(xué)院,江蘇 張家港 215600)
摘要: IoC是一種優(yōu)秀的組件解耦模式,而依賴(lài)注入是IoC最流行的實(shí)現(xiàn)方式。探討了依賴(lài)注入的三種不同的實(shí)現(xiàn)方式:構(gòu)造器注入、屬性注入以及接口注入,并介紹了IoC容器Unity的基本使用方法。
Abstract:
Key words :

  周洪斌

  (沙洲職業(yè)工學(xué)院,江蘇 張家港 215600)

      摘要:IoC是一種優(yōu)秀的組件解耦模式,而依賴(lài)注入是IoC最流行的實(shí)現(xiàn)方式。探討了依賴(lài)注入的三種不同的實(shí)現(xiàn)方式:構(gòu)造器注入、屬性注入以及接口注入,并介紹了IoC容器Unity的基本使用方法。

  關(guān)鍵詞依賴(lài)倒置原則控制反轉(zhuǎn);依賴(lài)注入;Unity

0引言

  2015年江蘇省高校大學(xué)生創(chuàng)新創(chuàng)業(yè)訓(xùn)練計(jì)劃立項(xiàng)項(xiàng)目(201511288009Y)在使用簡(jiǎn)單三層架構(gòu)開(kāi)發(fā)數(shù)據(jù)庫(kù)應(yīng)用程序時(shí),一般都是在業(yè)務(wù)邏輯層直接創(chuàng)建數(shù)據(jù)訪問(wèn)層相應(yīng)的對(duì)象,如:

  public class ProductBLL

  {

  SqlServerDAL dal = new SqlServerDAL();

  public int Add(ProductModel model)

  {

  return dal.Add(model);

  }

  }

  這種方式下由調(diào)用者ProductBLL主動(dòng)創(chuàng)建被依賴(lài)對(duì)象SqlServerDAL,然后調(diào)用被依賴(lài)對(duì)象的方法,導(dǎo)致調(diào)用者與被依賴(lài)對(duì)象實(shí)現(xiàn)類(lèi)的硬編碼耦合,不利于項(xiàng)目的維護(hù)與升級(jí)。上述緊耦合的業(yè)務(wù)邏輯層與數(shù)據(jù)訪問(wèn)層的關(guān)系如圖1所示。

  

001.jpg

  如果用戶需要將數(shù)據(jù)庫(kù)換成Access或者M(jìn)ySQL,需要修改ProductBLL類(lèi)內(nèi)部的代碼,違反了開(kāi)放封閉原則。開(kāi)放封閉原則要求“軟件實(shí)體(類(lèi)、模塊、函數(shù)等)對(duì)擴(kuò)展是開(kāi)放的,對(duì)修改是封閉的”。依賴(lài)倒置原則(Dependency Inversion Principle,DIP)要求“高層模塊不應(yīng)該依賴(lài)于低層模塊,兩者應(yīng)該依賴(lài)于抽象”[1]。因此,業(yè)務(wù)邏輯層的對(duì)象不應(yīng)該直接依賴(lài)于數(shù)據(jù)訪問(wèn)層的具體實(shí)現(xiàn)對(duì)象,而應(yīng)該通過(guò)數(shù)據(jù)訪問(wèn)層的抽象接口進(jìn)行訪問(wèn),如圖2所示。通過(guò)引入抽象,對(duì)于高層模塊而言,低層模塊的實(shí)現(xiàn)是可替換的。這實(shí)際上也是“開(kāi)放封閉原則”的體現(xiàn)。

  

002.jpg

1控制反轉(zhuǎn)

  DIP作為一種軟件設(shè)計(jì)原則,指明了兩個(gè)模塊之間應(yīng)該如何依賴(lài)。而控制反轉(zhuǎn)(Inversion of Control,IoC)則是一種具體的軟件設(shè)計(jì)模式,明確了如何解除相互依賴(lài)的模塊之間的耦合。IoC是指應(yīng)用本身不負(fù)責(zé)依賴(lài)對(duì)象的創(chuàng)建和維護(hù),而交給一個(gè)外部容器來(lái)完成。這樣就將控制權(quán)由應(yīng)用轉(zhuǎn)移到了外部,實(shí)現(xiàn)了控制權(quán)的反轉(zhuǎn)[2]。IoC的作用在于降低組件之間的耦合度,減少組件之間的依賴(lài)關(guān)系,提高程序的靈活性和可維護(hù)性。

  依賴(lài)注入(Dependency Injection,DI)是IoC模式最流行的實(shí)現(xiàn)方式,即由外部容器在運(yùn)行時(shí)動(dòng)態(tài)地將依賴(lài)的對(duì)象注入到組件中。通過(guò)依賴(lài)注入,業(yè)務(wù)邏輯層將不再需要直接創(chuàng)建數(shù)據(jù)訪問(wèn)層的對(duì)象,從而降低了兩者之間的耦合度。

2依賴(lài)注入

  依賴(lài)注入提供一種機(jī)制,將需要依賴(lài)(低層模塊)對(duì)象的引用傳遞給被依賴(lài)(高層模塊)對(duì)象。具體的依賴(lài)注入可以分為三種形式,即構(gòu)造器注入、屬性注入以及接口注入[3]。

  2.1構(gòu)造器注入

  構(gòu)造器注入,即通過(guò)構(gòu)造方法傳遞依賴(lài)。根據(jù)依賴(lài)倒置原則,高層模塊不應(yīng)該依賴(lài)于低層模塊,兩者應(yīng)該依賴(lài)于抽象。因此構(gòu)造方法的參數(shù)應(yīng)該是一個(gè)抽象類(lèi)型。

  首先,需要定義一個(gè)接口IDataAccess,并在IDataAccess接口中聲明一個(gè)Add方法,代碼如下:

  public interface IDataAccess

  {

  int Add(ProductModel model);

  }

  然后,在SqlServerDAL類(lèi)中,實(shí)現(xiàn)IDataAccess接口,代碼如下:

  public class SqlServerDAL:IDataAccess

  {

  public int Add(ProductModel model)

  {

  //省略具體數(shù)據(jù)庫(kù)操作代碼

  }

  }

  接下來(lái),修改ProductBLL類(lèi)的代碼,代碼如下:

  public class ProductBLL

  {

  private IDataAccess dal;

  //構(gòu)造器注入

  public ProductBLL(IDataAccess dal)

  {

  this.dal=dal;//傳遞依賴(lài)

  }

  public int Add(ProductModel model)

  {

  return dal.Add(model);

  }

  }

  在這里,將依賴(lài)對(duì)象SqlServerDAL對(duì)象的創(chuàng)建和綁定轉(zhuǎn)移到ProductBLL類(lèi)的外部來(lái)實(shí)現(xiàn),這樣就解除了兩者之間的緊耦合關(guān)系。這時(shí),如果要將數(shù)據(jù)庫(kù)換成Access數(shù)據(jù)庫(kù)時(shí),只需定義一個(gè)AccessDAL類(lèi),實(shí)現(xiàn)IDataAccess接口,然后在外部重新綁定依賴(lài),不需要修改ProductBLL類(lèi)內(nèi)部代碼即可實(shí)現(xiàn)對(duì)Access數(shù)據(jù)庫(kù)的操作。

  2.2屬性注入

  屬性注入,即通過(guò)屬性來(lái)傳遞依賴(lài)。因此,首先需要在依賴(lài)類(lèi)ProductBLL中定義一個(gè)屬性,代碼如下:

  public class ProductBLL

  {

  private IDataAccess dal;

  //屬性,接受依賴(lài)

  public IDataAccess Dal

  {

  set { dal = value; }

  get { return dal; }

  }

  public int Add(ProductModel model)

  {

  return dal.Add(model);

  }

  }

  然后在外部通過(guò)給Dal屬性賦值,從而傳遞依賴(lài)。

  2.3接口注入

  接口注入需要先定義一個(gè)接口,包含一個(gè)設(shè)置依賴(lài)的方法。然后由依賴(lài)類(lèi)繼承并實(shí)現(xiàn)這個(gè)接口。

  首先定義一個(gè)接口,代碼如下:

  public interface IDependent

  {

  void SetDependence(IDataAccess dal);//設(shè)置依賴(lài)項(xiàng)

  }

  依賴(lài)類(lèi)實(shí)現(xiàn)這個(gè)接口,代碼如下:

  public class ProductBLL:IDependent

  {

  private IDataAccess dal;

  //實(shí)現(xiàn)接口

  public void SetDependence(IDataAccess dal)

  {

  this.dal = dal;

  }

  public int Add(ProductModel model)

  {

  return dal.Add(model);

  }

  }

  外部則通過(guò)SetDependence方法傳遞依賴(lài)。相比構(gòu)造器注入和屬性注入,接口注入顯得有些復(fù)雜,使用也不常見(jiàn)。

3IoC容器

  3.1IoC容器概述

  一般在小型項(xiàng)目中可以手動(dòng)創(chuàng)建依賴(lài)對(duì)象,并將引用傳遞給被依賴(lài)模塊。如:

  IDataAccess dal=new SqlServerDAL();//在外部創(chuàng)建依賴(lài)對(duì)象

  ProductBLL bll=new ProductBLL(dal);//通過(guò)構(gòu)造器注入依賴(lài)

  對(duì)于大型項(xiàng)目來(lái)說(shuō),相互依賴(lài)的組件比較多,如果還用手動(dòng)的方式來(lái)創(chuàng)建和注入依賴(lài),效率較低。正因如此,IoC容器誕生了。IoC容器實(shí)際上是一個(gè)依賴(lài)注入框架,它包含以下幾個(gè)功能:

  (1)動(dòng)態(tài)創(chuàng)建、注入依賴(lài)對(duì)象;

  (2)管理對(duì)象生命周期;

  (3)映射依賴(lài)關(guān)系。

  Spring是Java平臺(tái)廣泛使用的IoC容器[4],.NET平臺(tái)常用的IoC容器包括Unity、Autofac、Spring.NET和Ninject等。Unity是微軟公司推出的一款輕量的、可擴(kuò)展的依賴(lài)注入容器,該項(xiàng)目在Codeplex上的地址為http://unity.codeplex.com,可以下載相應(yīng)的安裝包和開(kāi)發(fā)文檔[5]。

  3.2Unity應(yīng)用

  Unity在實(shí)際項(xiàng)目中的使用方法如下[6]:

  (1)添加對(duì)Microsoft.Practices.Unity.dll、Microsoft.Practices.Unity.Configuration.dll以及Microsoft.Practices.Unity.RegistrationByConvention.dll的引用。

  (2)在項(xiàng)目配置文件的<configSections>節(jié)點(diǎn)下注冊(cè)名為unity的section,并在<configuration>節(jié)點(diǎn)下添加unity配置信息。配置文件樣例如下:

  <?xml version="1.0" encoding="utf-8" ?>

  <configuration>

  <configSections>

  <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/>

  </configSections>

  <unity>

  <container name="MyContainer">

  <!--映射關(guān)系-->

  <register type="UnityDemo.IDataAccess,UnityDemo"mapTo="UnityDemo.SqlServerDAL,UnityDemo"></register>

  </container>

  </unity>

  <startup>

  <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />

  </startup>

  </configuration>

  (3)在代碼中讀取配置信息,并將配置載入到UnityContainer中。

  //創(chuàng)建容器

  IUnityContainer container = new UnityContainer();

  //載入配置信息

  container.LoadConfiguration("MyContainer");

  //獲取指定名稱(chēng)的配置節(jié)

  UnityConfigurationSection section

  = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

  //獲取特定配置節(jié)下已命名的配置節(jié)<container name='MyContainer'>下的配置信息

  section.Configure(container, "MyContainer");

  //創(chuàng)建實(shí)現(xiàn)了IDataAccess接口的對(duì)象

  IDataAccess dal = container.Resolve<IDataAccess>();

4結(jié)論

  IoC能有效降低組件之間的耦合度,提高程序的靈活性和可擴(kuò)展性。本文圍繞如何實(shí)現(xiàn)業(yè)務(wù)邏輯層與數(shù)據(jù)訪問(wèn)層之間的松散耦合,介紹了構(gòu)造器注入、屬性注入以及接口注入三種不同的依賴(lài)注入方式,并介紹了NET平臺(tái)下常用IoC容器Unity的使用,展示了IoC在軟件開(kāi)發(fā)領(lǐng)域的實(shí)際應(yīng)用。

參考文獻(xiàn)

  [1] 張逸.軟件設(shè)計(jì)精要與模式(第2版)[M].北京:電子工業(yè)出版社,2010.

  [2] 王程,周安琳.基于Autofac對(duì)乳制品安全風(fēng)險(xiǎn)預(yù)警系統(tǒng)的擴(kuò)展設(shè)計(jì)[J].河北省科學(xué)院學(xué)報(bào),2013,30(1):14.

  [3] 張浩.利用反向控制原則和依賴(lài)注入的可復(fù)用框架設(shè)計(jì)解耦方法[J].計(jì)算機(jī)應(yīng)用,2010(12):227229.

  [4] 周嵐.基于Spring框架的IoC模式的設(shè)計(jì)和實(shí)現(xiàn)[J].合肥學(xué)院學(xué)報(bào)(自然科學(xué)版),2011,21(1):4953.

  [5] 李鳳桐.微軟企業(yè)庫(kù)組件Unity使用淺析[J].電腦編程技巧與維護(hù),2015(6):1314.

  [6] 蔣金楠.ASP.NET MVC4框架揭秘[M].北京:電子工業(yè)出版社,2013.


此內(nèi)容為AET網(wǎng)站原創(chuàng),未經(jīng)授權(quán)禁止轉(zhuǎn)載。
主站蜘蛛池模板: 久久精品资源站| 人人人妻人人澡人人爽欧美一区| 欧美jizz18欧美| 国产羞羞视频在线播放| juy031白木优子中文字幕| 我的娇妻acome| 久久国产精品无码一区二区三区| 欧美xxxxx高潮喷水| 亚洲欧美另类日韩| 男女一进一出抽搐免费视频| 另类国产ts人妖系列| 菠萝蜜视频在线观看| 国产女人乱人伦精品一区二区| 把女人的嗷嗷嗷叫视频软件| 国产观看精品一区二区三区| 99爱在线精品视频网站| 好好的日视频www| 一级做a爰片性色毛片中国| 成年男人的天堂| 久久久久亚洲AV成人片| 日本高清视频wwww色| 久久黄色免费网站| 欧亚专线欧洲s码wm| 亚洲国产精品福利片在线观看| 毛片a级毛片免费观看免下载| 人妻老妇乱子伦精品无码专区| 精品一区二区久久久久久久网站| 噜噜噜噜私人影院| 色偷偷女男人的天堂亚洲网| 国产乱妇乱子在线播视频播放网站| 91手机看片国产永久免费| 国产激情视频在线| 中文字幕一区二区三匹| 国产精品久久久久久久久电影网| 3d动漫精品一区二区三区| 国产网红在线观看| 67194成是人免费无码| 国产香蕉97碰碰视频VA碰碰看| 99久久人妻无码精品系列蜜桃 | 国产精品12页| 窝窝女人体国产午夜视频|