前言:在上一篇中,我們簡單的介紹了導入和導出的基本知識以及一些基本用法,本篇將介紹一下在導出中經常使用的到兩種技巧(其實就是MEF提供的兩種特性):元數據(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中可以對Export 和 InheritedExport 進行擴展,用於將元數據封裝到自定義特性中。
自定義特性可以指定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; }
}
使用自定義導出修飾前面導出:
[FileLogExport("FileLog"))
public class FileLog: ILog
{
}
使用自定義導出的特性,ContractType是隱式定義的,
“在必須將大量的相同元數據(例如,作者或版權信息)應用於多個部件的情況下,使用自定義特性可以節約大量的時間和重複工作。 此外,可以創建自定義特性的繼承樹來爲變體留出餘地。
若要在自定義特性中創建可選元數據,您可以使用 DefaultValue 特性。 如果此特性應用於自定義特性類中的屬性,它將指定修飾的屬性是可選的,並且不必由導出程序提供。 如果未提供屬性的值,則將爲屬性分配其屬性類型的默認值(通常爲 null、false 或 0。)”——MSDN
結束語:MEF中導入是不能進行自定義的,但MEF中得導出和元數據的配合使得導出更加靈活。
本文主要參考:http://msdn.microsoft.com/zh-cn/library/ee155691.aspx