MEF 導入(Import)和導出(Export)


前言:

MEF不同於其他IOC容器(如:Castle)很重要的原因在於它使用了特性化編程模型(涉及到兩個概念:“特性”和“編程模型”)。

特性(Attribute):舉例來說就是我們在開發過程中在類上標記的如:[Serializable]的標簽。

編程模型(Programming Model):MEF中的編程模型是定義 MEF 所操作的概念性對象集的特定方法。MEF默認使用特性化編程模型,但是用戶也可自定義編程模型。MEF中導入、導出間的匹配均是通過特性來實現的。本文簡單的介紹下MEF中得導入和導出。

導入和導出基礎:

在上一篇文章中我們說過導出提供服務,而導入是使用服務。導入使用 Import特性聲明 ,導出使用 Export 特性聲明。 Export 特性可修飾類、字段、屬性或方法,而 Import 特性可修飾字段、屬性或構造函數參數。導入和導出的匹配必須要有相同的Contract,Contract有兩部分組成:ContractName(名稱)和ContractType(類型),只有名稱和類型都完全相同,才會認為導出能夠滿足特定導入。如:

View Code  1 public interface ILog 2 { 3      void Log(Exception ex); 4 } 5 6 //導出的類型為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         //導入的類型默認為ILog,可以與導出匹配    [Import] 17     pulic Ilog MyLog 18     { 19         get; 20         set; 21     } 22 }

導入的類型:

MEF中導入的類型包括了:動態導入、延遲導入、必備導入和可選導入。

動態導入:使用dynamic關鍵字進行導入,協定類型從 dynamic 關鍵字推斷而出,則它將與任何協定類型匹配。所以在使用倒台導入時必須指定協定名稱,否則將未匹配任何導出

1 public class MyClass 2 { 3     [Import(“MyLog”)] 4     public dynamic MyLog{ get; set; } 5 }

延遲導入:我們知道延遲加載,那么延遲導入同延遲加載的作用一樣:導入和導出匹配時不會立即實例化對象,延遲導入需要使用Lazy<T>來聲明導入:

1 public class MyClass 2 { 3     [Import] 4     public Lazy<ILog> MyLog { get; set; } 5 }

 

必備導入:在我們的日常工作中我們可能經常會用到依賴注入,依賴注入有一種方式便是通過構造函數將我們需要的對象注入到本類中,MEF也可以完成相同的工作。

    導出的 MEF 部件通常由組合引擎創建,默認情況下,在創建部件時,組合引擎將使用無參數的構造函數。要想使用自定義構造函數需要使用特性:ImportingConstructor。使用必備導入時必須同時提供默認構造和ImportingConstructor的構造方法,否則將出錯.MEF允許導入和導出的循環依賴。

 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 }

 

可選導入:在MEF中如果導入得不到匹配將會組合失敗,但我們需要容錯時,使用AllowDefault 屬性指定導入為可選:[Import(AllowDefault = true)]。這樣即使導入沒有得到匹配也不會影響組合容器對部件的組合。

導入多個對象:導入和導出可以支持一對多的關系,使用ImportMany特性可以導入多個服務(導出),使用ImportMany標記的導入始終是可選導入。

1 public class MyClass 2 { 3     [ImportMany] 4     public IEnumerable<ILog> MyLogs { get; set; } 5 }

導入和導出的繼承

導入的繼承:導入始終由子類繼承,子類擁有和父類相同的導入。

導出的繼承:使用Export特性的導出部件始終不能唄繼承,如果想要導出部件可以被繼承需要使用關鍵字:InheritedExport,子類將提供與父類相同的導出(包括ContractName和ContractType)。但是InheritedExport只能標記在類上,也就是說成員導出永遠不能被繼承。

后記:導入和導出相關的概念還包括元數據,以及自定義導出相關知識,將在下一篇中詳細介紹。

本文參考:http://msdn.microsoft.com/zh-cn/library/ee155691.aspx#MtViewDropDownText

 

作者:ps_zw

出處:http://www.cnblogs.com/pszw/

本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM