MEF初体验之十二:Composition Batch
一个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); } } }