MEF学习笔记(2)——创建MEF
建立MEF包含CompositionContainer的实例,给它增加Composable part(包含程序自己本身),然后组合。
以下是建立的顺序
- 创建宿主类。在示例中,我们使用命令行程序,所以宿主在Program类。
- 增加System.ComponentModel.Composition引用。
- 增加如下命名空间:using System.Component.Composition
- 增加Compose()方法,创建container实例,然后组装。
- 增加Run()方法,它调用Compose()。
- 在Main()函数中,启动宿主。
注意,对于ASP.NET和WPF程序来讲,创建宿主类没有必要。
请看代码:
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 composable part,它exports一个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. 给宿主类增加属性,并用Import标签标记。
[Import]
public IMessageSender MessageSender { get; set; }
9. 增加part到container。在MEF中,有很多种方式来做。一种是直接增加composable part的实例。另一种,更常见的是使用catalog。
直接增加composable part实例
在Compose()方法手动增加一个composable part,使用ComposePart()扩展方法。如下:
private void Compose()
{
var container = new CompositionContainer();
container.ComposeParts(this, new EmailSender());
}
使用AssemblyCatalog来增加Container
使用catablog,container自动处理创建的parts,而不是显示增加他们。为了这样做,在Compose()方法中创建一个catalog。然后传入container的构造函数。
在这个例子中,AssemblyCatalog显示将正在执行的程序集传入构造函数。我们没有增加EmailSender的实例。
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);
}
}