MEF 导入(Import)和导出(Export)
前言:
MEF不同于其他IOC容器(如:Castle)很重要的原因在于它使用了特性化編程模型(涉及到兩個(gè)概念:“特性”和“編程模型”)。
特性(Attribute):舉例來說就是我們?cè)陂_發(fā)過程中在類上標(biāo)記的如:[Serializable]的標(biāo)簽。
編程模型(Programming Model):MEF中的編程模型是定義 MEF 所操作的概念性對(duì)象集的特定方法。MEF默認(rèn)使用特性化編程模型,但是用戶也可自定義編程模型。MEF中導(dǎo)入、導(dǎo)出間的匹配均是通過特性來實(shí)現(xiàn)的。本文簡(jiǎn)單的介紹下MEF中得導(dǎo)入和導(dǎo)出。
導(dǎo)入和導(dǎo)出基礎(chǔ):
在上一篇文章中我們說過導(dǎo)出提供服務(wù),而導(dǎo)入是使用服務(wù)。導(dǎo)入使用 Import特性聲明 ,導(dǎo)出使用 Export 特性聲明。 Export 特性可修飾類、字段、屬性或方法,而 Import 特性可修飾字段、屬性或構(gòu)造函數(shù)參數(shù)。導(dǎo)入和導(dǎo)出的匹配必須要有相同的Contract,Contract有兩部分組成:ContractName(名稱)和ContractType(類型),只有名稱和類型都完全相同,才會(huì)認(rèn)為導(dǎo)出能夠滿足特定導(dǎo)入。如:
View Code ?1 public interface ILog 2 { 3????? void Log(Exception ex); 4 } 5 6 //導(dǎo)出的類型為ILog[Export(typeof(ILog))] 7 pulic class FileLog:ILog 8 { 9????? public void Log(Exception ex) 10????? { 11????? } 12 } 13 14 pulic class MyClass 15 { 16???????? //導(dǎo)入的類型默認(rèn)為ILog,可以與導(dǎo)出匹配??? [Import] 17???? pulic Ilog MyLog 18???? { 19???????? get; 20???????? set; 21???? } 22 }
導(dǎo)入的類型:
MEF中導(dǎo)入的類型包括了:動(dòng)態(tài)導(dǎo)入、延遲導(dǎo)入、必備導(dǎo)入和可選導(dǎo)入。
動(dòng)態(tài)導(dǎo)入:使用dynamic關(guān)鍵字進(jìn)行導(dǎo)入,協(xié)定類型從 dynamic 關(guān)鍵字推斷而出,則它將與任何協(xié)定類型匹配。所以在使用倒臺(tái)導(dǎo)入時(shí)必須指定協(xié)定名稱,否則將未匹配任何導(dǎo)出
1 public class MyClass 2 { 3???? [Import(“MyLog”)] 4???? public dynamic MyLog{ get; set; } 5 }
延遲導(dǎo)入:我們知道延遲加載,那么延遲導(dǎo)入同延遲加載的作用一樣:導(dǎo)入和導(dǎo)出匹配時(shí)不會(huì)立即實(shí)例化對(duì)象,延遲導(dǎo)入需要使用Lazy<T>來聲明導(dǎo)入:
1 public class MyClass 2 { 3???? [Import] 4???? public Lazy<ILog> MyLog { get; set; } 5 }
?
必備導(dǎo)入:在我們的日常工作中我們可能經(jīng)常會(huì)用到依賴注入,依賴注入有一種方式便是通過構(gòu)造函數(shù)將我們需要的對(duì)象注入到本類中,MEF也可以完成相同的工作。
??? 導(dǎo)出的 MEF 部件通常由組合引擎創(chuàng)建,默認(rèn)情況下,在創(chuàng)建部件時(shí),組合引擎將使用無參數(shù)的構(gòu)造函數(shù)。要想使用自定義構(gòu)造函數(shù)需要使用特性:ImportingConstructor。使用必備導(dǎo)入時(shí)必須同時(shí)提供默認(rèn)構(gòu)造和ImportingConstructor的構(gòu)造方法,否則將出錯(cuò).MEF允許導(dǎo)入和導(dǎo)出的循環(huán)依賴。
?1 public class MyClass 2 { 3???? private ILog _myLog; 4 5???? public MyClass() { } 6 7???? [ImportingConstructor] 8???? public MyClass(ILog myLog) 9???? { 10???????? _myLog = myLog; 11???? } 12 }
?
可選導(dǎo)入:在MEF中如果導(dǎo)入得不到匹配將會(huì)組合失敗,但我們需要容錯(cuò)時(shí),使用AllowDefault 屬性指定導(dǎo)入為可選:[Import(AllowDefault = true)]。這樣即使導(dǎo)入沒有得到匹配也不會(huì)影響組合容器對(duì)部件的組合。
導(dǎo)入多個(gè)對(duì)象:導(dǎo)入和導(dǎo)出可以支持一對(duì)多的關(guān)系,使用ImportMany特性可以導(dǎo)入多個(gè)服務(wù)(導(dǎo)出),使用ImportMany標(biāo)記的導(dǎo)入始終是可選導(dǎo)入。
1 public class MyClass 2 { 3???? [ImportMany] 4???? public IEnumerable<ILog> MyLogs { get; set; } 5 }
導(dǎo)入和導(dǎo)出的繼承
導(dǎo)入的繼承:導(dǎo)入始終由子類繼承,子類擁有和父類相同的導(dǎo)入。
導(dǎo)出的繼承:使用Export特性的導(dǎo)出部件始終不能唄繼承,如果想要導(dǎo)出部件可以被繼承需要使用關(guān)鍵字:InheritedExport,子類將提供與父類相同的導(dǎo)出(包括ContractName和ContractType)。但是InheritedExport只能標(biāo)記在類上,也就是說成員導(dǎo)出永遠(yuǎn)不能被繼承。
后記:導(dǎo)入和導(dǎo)出相關(guān)的概念還包括元數(shù)據(jù),以及自定義導(dǎo)出相關(guān)知識(shí),將在下一篇中詳細(xì)介紹。
本文參考:http://msdn.microsoft.com/zh-cn/library/ee155691.aspx#MtViewDropDownText
?
作者:ps_zw
出處:http://www.cnblogs.com/pszw/
本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利.
轉(zhuǎn)載于:https://www.cnblogs.com/zjoch/p/3652789.html
總結(jié)
以上是生活随笔為你收集整理的MEF 导入(Import)和导出(Export)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: powerdesigner 技巧
- 下一篇: gedit搭建c开发环境