在MEF中,使用[System.ComponentModel.Composition.ExportAttribute]支持多種級別的導出部件配置,包括類、字段、屬性以及方法 級別的導出部件,通過查看ExportAttribute的源代碼就知道ExportAttribute被定義為 Attribute,並為其設置了使用范圍。
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes")]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method,
AllowMultiple = true, Inherited = false)]
public class ExportAttribute : Attribute
{
//......
}
當任何一個類對象或是其內部的字段、屬性、方法需要作為可組合部件的時候,就可以使用[ExportAttribute]將其標注為可導出部件 。比如需要將一個對象做為可組合部件進行導出(就是類級別的導出),只需要在類上添加[ExportAttribute]就行了,詳細的應用可參考 《MEF中組合部件(Composable Parts)與契約(Contracts)的基本應用》,下面為演示代碼:
[System.ComponentModel.Composition.Export]
public class DBLogger
{
}
對於字段、屬性級別的導出同類是一樣的,通樣使用[ExportAttribute]進行標注,下面代碼塊演示了一個完整的屬性導入與導出的示 例。
namespace MEFTraining.ExmprtImport
{
public partial class MainPage : UserControl
{
[Import("Name")]
public string BookName { get; set; }
public MainPage()
{
InitializeComponent();
CompositionInitializer.SatisfyImports(this);
MessageBox.Show(BookName);
}
}
public class BookService
{
[Export("Name")]
public string BookName
{
get { return "《MEF程序設計指南》"; }
}
}
}
方法級的導入與導出主要是利用委托實現,既Action或Action<T>,其使用也是非常簡單的,無論是方法所需的參數還是返回值 ,都可以通過匿名委托去實現。如下代碼中定義了一個BookService類,裡面通過MEF導出了PrintBookName方法,且帶有一個字符串類型參 數,此時就可以通過匿名委托進行形參的和方法的導出。
public class BookService
{
[Export(typeof(Action<string>))]
public void PrintBookName(string name)
{
Console.WriteLine(name);
}
}
在需要使用到此方法的地方,只需要通過匿名委托的方法對該方法進行導入就可以了,下面的代碼是對上面的導出方法的調用示例。
public partial class MethodExportImport : UserControl
{
[Import(typeof(Action<string>))]
public Action<string> PrintBookName { get; set; }
public MethodExportImport()
{
InitializeComponent();
CompositionInitializer.SatisfyImports(this);
PrintBookName("《MEF程序設計指南》");
}
}
另外,MEF也支持繼承的導入與導出應用,使用 [System.ComponentModel.Composition.InheritedExportAttribute]實現基於繼承的導 出,其他的和字段、屬性、方法級的應用完全一致,下面的代碼演示了基於繼承的導出與導出應用。
namespace MEFTraining.ExmprtImport
{
public partial class InheritedExportImport : UserControl
{
[Import]
public IUserServie UService { get; set; }
public InheritedExportImport()
{
InitializeComponent();
CompositionInitializer.SatisfyImports(this);
string name = UService.GetUserName();
}
}
[InheritedExport]
public interface IUserServie
{
string GetUserName();
}
public class UserService : IUserServie
{
public string GetUserName()
{
return "張三";
}
}
}
MEF還支持構造方法參數的導入,詳細這裡就不介紹了,有興趣的可直接查詢MEF英文版程序設計指南介紹。