一个MEF容器实例是不可变的。如果catalog支持改变(像观察一个目录的改变)或是如果你的代码在运行时添加或移除部件,改变都可能发生。以前,你不得不作出改变并在组合容器上调用它的组合方法。在Preview 4 版中,我们已经介绍了对Composition Batch的支持。
批处理包含了一系列要添加或移除的部件。变化执行后,容器将自动地触发重合,这将更新受变化影响的可重组导入。考虑这样一个场景,一个设置窗口和一个用户选择和取消选择项。这些将导致映射到当前容器中部件与否。为了应用batch,你将调用Compose方法,如下:
var batch = new CompositionBatch();
batch.AddPart(partInstance1);
batch.AddPart(partInstance2);
batch.RemovePart(part3); container.Compose(batch);
实际上,对于那些使用基于特性编程模型的类型来说,针对组合容器有一些与AttributedModelServices相关的扩展,这个组合容器将允许你在不需要CompostionBatch的地方,可以隐藏它。
// creates a CompositionBatch and calls AddPart on all the passed parts followed by Compose
container.ComposeParts(partInstance1, partInstance2,... );
// creates a CompositionBatch and calls AddExportedValue<T> followed by Compose.
container.ComposeExportedValue<IFoo>(instanceOfIFoo);
来举个简单的例子:
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace CompositonBatchExample
{
class Program
{
[Import]
public IMessageSender Sender { get; set; }
static void Main(string[] args)
{
Program p = new Program();
p.Run();
p.Sender.Send("Hi,MEF");
Console.ReadKey();
}
void Run()
{
var container = new CompositionContainer();
//container.ComposeParts(this, new EmailSender());//等价于下面几行
var batch = new CompositionBatch();
batch.AddPart(this);
ComposablePart part = batch.AddPart(new EmailSender());
//container.ComposeExportedValue<IMessageSender>(new TcpSender());
container.Compose(batch);
}
}
interface IMessageSender
{
void Send(string msg);
}
[Export(typeof(IMessageSender))]
class EmailSender : IMessageSender
{
public void Send(string msg)
{
Console.WriteLine("Email sent:" + msg);
}
}
[Export(typeof(IMessageSender))]
class TcpSender : IMessageSender
{
public void Send(string msg)
{
Console.WriteLine("Tcp Sent:" + msg);
}
} }