一、 MEF 宿主
在主应用中使用MEF主要包括两部分:创建一个CompositionContainer实例,新增组件并将新增的组件加入到主应用中使用。
在主应用中加入MEF的步骤如下:
1. 创建一个console 应用程序;
2. 创建一个宿主类。在本例中的,宿主类为Program;
3. 在应用程序中引用动态库System.ComponentModel.Composition;
4. 在Program 类中 添加using System.ComponentModel.Composition;
5. 新增一个 Compose() 方法。该方法用来创建一个container实例 并且将组建加载到主应用中;
6. 新增一个 Run() 方法。该方法用来调用 Compose() 方法;
7. 在Main() 方法中使用该宿主类。
using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; using System.Reflection; using System; public class Program { public static void Main(string[] args) { Program p = new Program(); p.Run(); } public void Run() { Compose(); } private void Compose() { var container = new CompositionContainer(); container.ComposeParts(this); } }
7. 定义一个或多个Exports组件类,这些组件类将被注入到主应用中使用。在下面示例中,定义了一个接口 IMessageSender 和 一个组件类 EmailSender。EmailSender组件类继承了接口IMessagesender并定义了一个[System.ComponentModel.Composition.Export] 的特性。
public interface IMessageSender { void Send(string message); } [Export(typeof(IMessageSender))] public class EmailSender : IMessageSender { public void Send(string message) { Console.WriteLine(message); } }
8. 在宿主类中定义一个带有[System.ComponentModel.Composition.Import] 特性的IMessageSender 属性。
[Import] public IMessageSender MessageSender { get; set; }
9. 将组件加入到主应用中。我们可以通过两种方法来实现:一种是直接实例化组件;另一种是通过catalog来使用组件。
9.1 直接实例化组件类
在Compose()方法中通过ComposeParts()方法添加所有实例化的组件。
private void Compose() { var container = new CompositionContainer(); container.ComposeParts(this, new EmailSender()); }
9.2 通过catalog来使用
通过catalog,container可以自动的创建并实例化组件。下面的示例中,通过AssemlyCatalog类来创建组件,而不需要实例组件。
private void Compose() { var catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()); var container = new CompositionContainer(catalog); container.ComposeParts(this); }
下面是本示例的完整源码:
using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; using System.Reflection; using System; public class Program { [Import] public IMessageSender MessageSender { get; set; } public static void Main(string[] args) { Program p = new Program(); p.Run(); } public void Run() { Compose(); MessageSender.Send("Message Sent"); } private void Compose() { AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); var container = new CompositionContainer(catalog); container.ComposeParts(this); } } public interface IMessageSender { void Send(string message); } [Export(typeof(IMessageSender))] public class EmailSender : IMessageSender { public void Send(string message) { Console.WriteLine(message); } }
当在visual studio中测试以上源码,继承了IMessageSender 的组件中的Send() 方法将在主应用中执行。