日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
MVC實(shí)用架構(gòu)設(shè)計(jì):使用MEF應(yīng)用IOC(依賴倒置)

一、前言

臨河網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)公司!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站設(shè)計(jì)等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營維護(hù)。成都創(chuàng)新互聯(lián)公司自2013年起到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選成都創(chuàng)新互聯(lián)公司。

在《上篇》中,基本的項(xiàng)目結(jié)構(gòu)已經(jīng)搭建起來了,但是有個(gè)問題,層與層之間雖然使用了接口進(jìn)行隔離,但實(shí)例化接口的時(shí)候,還引入了接口實(shí)現(xiàn)類的依賴。如下圖:

面向接口編程,Controller應(yīng)該只依賴于站點(diǎn)業(yè)務(wù)層的接口,而不能依賴于具體的實(shí)現(xiàn),否則,就違背了在層之間設(shè)置接口的初衷了。

另外,如果上層只依賴于下層的接口,在做單元測(cè)試的時(shí)候,就可以用Moq,F(xiàn)akes等Mock工具來按實(shí)際需求來模擬接口的實(shí)現(xiàn),就可以靈活的控制接口的返回值來對(duì)各種情況進(jìn)行測(cè)試,如果依賴于具體的實(shí)現(xiàn),項(xiàng)目的可測(cè)試性將大大減小,不利于進(jìn)行自動(dòng)化的單元測(cè)試。

要不依賴于具體的實(shí)現(xiàn),就不能使用通常的 T t = new T() 的方式來獲得一個(gè)類的實(shí)例了,需要通過IOC容器來對(duì)對(duì)象生命周期,依賴關(guān)系等進(jìn)行統(tǒng)一的管理。

二、MEF的優(yōu)勢(shì)

.net中可用的IOC容器非常多,如 CastleWindsor,Unity,Autofac,ObjectBuilder,StructureMap,Spring.Net等,這些第三方工具各不相同,但功能大體都相同,大都需要事先對(duì)接口與實(shí)現(xiàn)進(jìn)行配對(duì)(通過代碼或配置文件),然后由系統(tǒng)自動(dòng)或手動(dòng)來通過接口來獲得相應(yīng)實(shí)現(xiàn)類的實(shí)例,對(duì)象實(shí)例化的工作由IOC容器自動(dòng)完成。

MEF相對(duì)于上面的這些IOC容器有什么優(yōu)勢(shì)呢?下面是我推薦的理由:

  1. .net4.0 自帶:MEF的功能在 System.ComponentModel.Composition.dll 程序集中,直接引用即可使用,不用安裝第三方組件
  2. 0 配置:MEF是不需要使用配置文件或代碼對(duì)接口與實(shí)現(xiàn)進(jìn)行一一配對(duì)的,只需要簡(jiǎn)單的使用幾個(gè)Attribute特性,就能自動(dòng)完成源與目標(biāo)的配對(duì)工作
  3. 自動(dòng)化:系統(tǒng)初始化時(shí)自動(dòng)遍歷程序目錄或指定文件夾下的dll,根據(jù)程序集中接口與類的特定Attribute特性進(jìn)行自動(dòng)配對(duì)。

三、MEF在桌面程序中的使用

在桌面程序中,需要完成兩個(gè)部分的目錄匹配,一個(gè)是dll中的匹配,另一個(gè)為exe程序集中的匹配,分別使用到 DirectoryCatalog與AssemblyCatalog兩個(gè)目錄類。而兩個(gè)目錄類需加入到 AggregateCatalog 目錄類中,才能參與組合容器CompositionContainer的初始化。

在服務(wù)提供方的實(shí)現(xiàn)類中,使用 ExportAttribute 標(biāo)記要與之匹配的接口,如下圖所示。在服務(wù)調(diào)用方,使用 ImportAttribute 來給接口注入實(shí)現(xiàn)類的實(shí)例,如上圖所示。

由于調(diào)用方法為靜態(tài)的方法,Program類的實(shí)例仍需手動(dòng)從組件容器中獲得,然后嘗試登錄:

輸出結(jié)果,接口AccountContract并沒有賦值,但能輸出其實(shí)現(xiàn)類的信息,同時(shí)登錄也能成功調(diào)用:

四、MEF在MVC中的使用

在MVC的項(xiàng)目中,IOC組件是通過 DependencyResolver類中的 SetResolver(IDependencyResolver resolver) 方法來向MVC提供注冊(cè)點(diǎn)的,所以我們只需要實(shí)現(xiàn)一個(gè) IDependencyResolver 接口的MEF實(shí)現(xiàn)類,即可完成MEF在MVC中的注冊(cè)工作。

另外考慮到Web應(yīng)用程序的無狀態(tài)性,即每次訪問都是獨(dú)立進(jìn)行的,所以IOC組件產(chǎn)生的對(duì)象實(shí)例也必須唯一,否則不同用戶的操作就可能串線,產(chǎn)生相互干擾。在這里,我們使用HttpContext.Current.Items集合來保存 組合容器CompositionContainer的實(shí)例,以使每個(gè)用戶的數(shù)據(jù)保持獨(dú)立,并且同一用戶的同一個(gè)Http請(qǐng)求中使用同一對(duì)象實(shí)例。另外考慮到可能會(huì)有某種情況下需要手動(dòng)獲取組合容器中的實(shí)例,把組合容器緩存到了當(dāng)前上下文中的Application中。

MefDependencySolver實(shí)現(xiàn)代碼如下: 

 
 
 
 
  1. ///   
  2.     /// MEF依賴關(guān)系解析類  
  3.     ///   
  4.     public class MefDependencySolver : IDependencyResolver  
  5.     {  
  6.         private readonly ComposablePartCatalog _catalog;  
  7.         private const string HttpContextKey = "MefContainerKey";  
  8.  
  9.         public MefDependencySolver(ComposablePartCatalog catalog)  
  10.         {  
  11.             _catalog = catalog;  
  12.         }  
  13.  
  14.         public CompositionContainer Container  
  15.         {  
  16.             get  
  17.             {  
  18.                 if (!HttpContext.Current.Items.Contains(HttpContextKey))  
  19.                 {  
  20.                     HttpContext.Current.Items.Add(HttpContextKey, new CompositionContainer(_catalog));  
  21.                 }  
  22.                 CompositionContainer container = (CompositionContainer)HttpContext.Current.Items[HttpContextKey];  
  23.                 HttpContext.Current.Application["Container"] = container;  
  24.                 return container;  
  25.             }  
  26.         }  
  27.  
  28.         #region IDependencyResolver Members  
  29.  
  30.         public object GetService(Type serviceType)  
  31.         {  
  32.             string contractName = AttributedModelServices.GetContractName(serviceType);  
  33.             return Container.GetExportedValueOrDefault(contractName);  
  34.         }  
  35.  
  36.         public IEnumerable GetServices(Type serviceType)  
  37.         {  
  38.             return Container.GetExportedValues(serviceType.FullName);  
  39.         }  
  40.  
  41.         #endregion  
  42.     } 
  43. #p#

    在Global.asax.cs的Application_Start方法中初始化MEF容器,由于Web應(yīng)用程序中只需要在DLL中查找匹配,所以只使用DirectoryCatalog即可。

    在AccountController類中加入MEF的Attribute標(biāo)簽,并刪除原來構(gòu)造函數(shù)中的AccountContract屬性的賦值代碼

    在加入了IOC組件之后,我們的架構(gòu)就變成了面向接口編程的架構(gòu)了,上層代碼僅依賴于下層的接口,而不依賴于下層的具體實(shí)現(xiàn),為了防止站點(diǎn)業(yè)務(wù)層的實(shí)現(xiàn)代碼中出現(xiàn)如下所示的代碼:

     

     
     
     
     
    1. IAccountSiteContract accountContract = new AccountSiteService(); 

    上一篇文章中也提到過,需要把站點(diǎn)業(yè)務(wù)層中的實(shí)現(xiàn)類的可訪問性由 public 修改為 Internal,以實(shí)現(xiàn)上層代碼對(duì)下層代碼的真正隔離。

    其他代碼不變,運(yùn)行網(wǎng)站,同樣能正常調(diào)用登錄功能

    ***,給個(gè)溫馨提示:

    MEF的導(dǎo)出導(dǎo)入是整體關(guān)聯(lián)的,只要樹中某一個(gè)部件匹配失敗,整個(gè)樹將無法實(shí)例化,也就是會(huì)出現(xiàn)Import的屬性值為null的情況,這種情況下,可以使用MEF開發(fā)團(tuán)隊(duì)提供的調(diào)試工具M(jìn)EFX來進(jìn)行問題的快速定位。具體使用方法參考如下:

    • 結(jié)構(gòu)分析工具 (Mefx)
    • 調(diào)試 MEF

    五、源碼獲取

    GMFrameworkForBlog2.zip

    為了讓大家能***時(shí)間獲取到本架構(gòu)的***代碼,也為了方便我對(duì)代碼的管理,本系列的源碼已加入微軟的開源項(xiàng)目網(wǎng)站 http://www.codeplex.com,地址為:

    https://gmframework.codeplex.com/

    可以通過下列途徑獲取到***代碼:

    • 如果你是本項(xiàng)目的參與者,可以通過VS自帶的團(tuán)隊(duì)TFS直接連接到 https://tfs.codeplex.com:443/tfs/TFS17 獲取***代碼
    • 如果你安裝有SVN客戶端(親測(cè)TortoiseSVN 1.6.7可用),可以連接到 https://gmframework.svn.codeplex.com/svn 獲取***代碼
    • 如果以上條件都不滿足,你可以進(jìn)入頁面 https://gmframework.codeplex.com/SourceControl/latest 查看***代碼,也可以點(diǎn)擊頁面上的 Download 鏈接進(jìn)行壓縮包的下載,你還可以點(diǎn)擊頁面上的 History 鏈接獲取到歷史版本的源代碼
    • 如果你想和大家一起學(xué)習(xí)MVC,學(xué)習(xí)EF,歡迎加入Q群:5008599(群發(fā)言僅限技術(shù)討論,拒絕閑聊,拒絕醬油,拒絕廣告)
    • 如果你想與我共同來完成這個(gè)開源項(xiàng)目,可以隨時(shí)聯(lián)系我。

    當(dāng)前題目:MVC實(shí)用架構(gòu)設(shè)計(jì):使用MEF應(yīng)用IOC(依賴倒置)
    網(wǎng)頁網(wǎng)址:http://www.5511xx.com/article/dpdopic.html