MEF應用(3) 導入導出續

元數據(Metadata)和自定義導出(Custom Export)

 

在MEF中,導出可提供自身的一些附加信息,我們稱之爲“元數據”。可通過元數據將導出的一些信息、屬性傳遞給導入。上一篇介紹導入的時候提到了ImportMany,在ImportMany的時候有時候可能需要根據特定的條件過濾一些匹配的導出,這時我們可以利用導出的元數據作依據。此外,由於導入部件可以使用元數據來決定要使用哪些導出,或收集有關導出的信息而不必構造導出。 因此,導入必須爲延遲導入才能使用元數據。

  使用元數據需要定義一個稱爲“元數據視圖”的接口,元數據視圖中有且只能定義只讀的屬性,可以使用特性

[DefaultValue]給屬性默認值,元數據視圖中定義的所有屬性在使用時都必須賦值,否則使用改元數據的導出將與任何導入匹配失敗,當然我們也可以使用[DefaultValue]設置默認值,這樣被[DefaultValue]修飾的屬性便可以認爲是可選屬性了。例:

public interface ILogMetadata
 {  
      [DefaultValue("FileLog")] 
      string LogType{ get; }
 
      string Name{ get; }
 }


使用元數據視圖的導出

[Export(typeof(ILog))]
[ExportMetadata("Name", "FileLog")]
[ExportMetadata("LogType", "FileLog")]
public class FileLog: ILog
{
}


 

注意:特性ExportMetadata的參數第一個爲屬性名稱,第二個是屬性的值。組合容器在組合時部件時會自動匹配所有的元數據視圖,如果有符合的元數據視圖則該導出部件視爲匹配成功。

匹配導入(匹配含有元數據修飾的導出,導入需要使用延時加載):

 

public class MyLog
 {
     [Import]
     public Lazy<ILog, ILogMetadata> singleLog   { get; set; }
 
    [ImportMany]
     public IEnumerable<Lazy<ILog, ILogMetadata>> logs;
 }


 

自定義導出

  在上面的示例中我們可能會想,當元數據視圖的的必選屬性有很多時,我們是不是得使用很多的[ExportMetadata]來修飾導出,另外元數據視圖的寫法也很容易出錯,其實MEF中可以對ExportInheritedExport 進行擴展,用於將元數據封裝到自定義特性中。

  自定義特性可以指定ContractType、ContractName或任何其他元數據。 爲了定義自定義特性,必須使用 MetadataAttribute 特性來修飾繼承自 ExportAttribute(或 InheritedExportAttribute)的類。 例:

 

[MetadataAttribute]
 [AttributeUsage(AttributeTargets.Class, AllowMultiple=true)]//指定特性的作用域
 public class FileLogExportAttribute : ExportAttribute
 {
     public FileLogExportAttribute(string logType) 
         : base(typeof(ILog))
     {
         LogType= logType;
         Name = "FileLog";
     }
 
     public string LogType{ get; private set; }
 
     public string Name{ get; private set; }
 
 
 }


使用自定義導出修飾前面導出:

1 [FileLogExport("FileLog"))
2 public class FileLog: ILog
3 {
4 }

使用自定義導出的特性,ContractType是隱式定義的,

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章