一些应用程序被设计成在运行时可以动态改变。例如,一个新的扩展被下载,或者因为其它的多种多样的原因其它的扩展变得不可用。MEF处理这些多样的场景是依赖我们称作重组的功能来实现的,它可已在最初的组合后改变导入的值。

导入可以通知MEF它通过[Import]使用Allowrecomposition属性来支持重组。看下面的代码片段:

[Export]
public class HttpServerHealthMonitor
{
[ImportMany(AllowRecomposition=true)]
public IMessageSender[] Senders { get; set; }
}

这告诉MEF,你的类准备来处理重组,并且,如果IMessageSender实现者可用性改变(一个新的实现者可用或不可用),这个集合将被改变以在catalog中反映此
变化。一旦部件选择了允许重组,无论什么时候在catalog中可用的实现者有改变,或实例被手动地从容器中添加/移除,这些
都将使可重组部件得到通知。

重组的附加说明

  • 当重组发生时,我们将用一个新的实例来替换集合/数组的实例,我们将不会更新已存在的实例。在上面的例子中,如果一个新的IMessageSender实例出现了,Senders将被一个新的数组完全替换。这是为了促进现场安全。
  • 重组几乎对于支持导入的所有类型都有效,像字段,属性和集合,但是它不支持构造器参数。
  • 如果你的类型碰巧实现了IPartImportsSatisfiedNotification接口,无论重组何时发生,导入完成也将会被调用

最后举个例子:

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using ClassLibrary2;
using System.Timers; namespace RecompositionExample
{
class Program
{
[ImportMany(AllowRecomposition=true)]
public IEnumerable<IMessageSender> Senders { get; set; }
static void Main(string[] args)
{
Program p = new Program();
p.Compose();
p.Print();
Console.ReadKey();
}
private AggregateCatalog catalog;
private Timer t;
void t_Elapsed(object sender, ElapsedEventArgs e)
{
catalog.Catalogs.Add(new DirectoryCatalog("Plugins", "*.dll"));
t.Enabled = false;
Console.WriteLine("-----------------");
Print();
}
void Compose()
{
catalog = new AggregateCatalog(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
t = new Timer();
t.Elapsed += t_Elapsed;
t.Start();
}
void Print()
{
foreach (var item in Senders)
{
item.Send("Hi,MEF");
}
}
}
[Export(typeof(IMessageSender))]
class EmailSender : IMessageSender
{
public void Send(string msg)
{
Console.WriteLine("Email sent:" + msg);
}
}
class TcpSender : IMessageSender
{
public void Send(string msg)
{
throw new NotImplementedException();
}
} }

MEF初体验之十:部件重组的更多相关文章

  1. MEF初体验之十二:Composition Batch

    一个MEF容器实例是不可变的.如果catalog支持改变(像观察一个目录的改变)或是如果你的代码在运行时添加或移除部件,改变都可能发生.以前,你不得不作出改变并在组合容器上调用它的组合方法.在Prev ...

  2. MEF初体验之二:定义组合部件和契约

    组合部件 在MEF中,一个组合部件就是一个组合单元,组合部件"出口"其它组合部件需要的服务并且从其它部件"进口"需要的服务.在MEF编程模型中,为了声明组合部件 ...

  3. MEF初体验之三:Exports声明

    组合部件通过[ExportAttribute]声明exports.在MEF中,有这么几种成员可声明exports的方式:组合部件(类).字段.属性和方法.我们来看下ExportAttribute类的声 ...

  4. MEF初体验之九:部件生命周期

    理解MEF容器中部件的生命周期及其含义是非常重要的.鉴于MEF重点在开放端应用程序,这将变得尤其重要的,一旦app ships和第三方扩展开始运行,作为应用程序的开发者将很好地控制这一系列的部件.生命 ...

  5. MEF初体验之七:Using Catalogs

    MEF特性化编程模型的价值主张之一是通过catalogs动态发现部件的能力.Catalogs允许应用程序很容易地消费那些通过[Export]已经自我注册的exports. Assembly Catal ...

  6. MEF初体验之四:Imports声明

    组合部件使用[System.ComponentModel.Composition.ImportAttribute]特性声明导入.与导出类似,也有几种成员支持,即为字段.属性和构造器参数.同样,我们也来 ...

  7. MEF初体验之八:过滤目录

    当在使用子容器的时候,基于某些具体标准来过滤目录可能是重要的.例如,基于部件的创建策略来过滤是很常见的.下面的代码片段演示了如何构建这种特别方法: var catalog = new Assembly ...

  8. MEF初体验之五:Lazy Exports

    在一个部件组合中,导入将触发一个部件或者多个部件的实例化,这些部件暴露了所需原请求部件的必要的导入.对于一些应用程序来说,延迟实例化-防止图结构下的递归组合-可能对于将创建一个长久复杂的开销很大而不必 ...

  9. MEF初体验之十一:查询组合容器

    查询组合容器 组合容器暴露了几个get exports的重载方法和导出对象和对象集合.你需要注意下面的行为: 当请求单个对象实例时,如果未发现导出,一个异常将被抛出 当请求单个对象实例时,如果发现超过 ...

随机推荐

  1. 【甘道夫】Win7x64环境下编译Apache Hadoop2.2.0的Eclipse小工具

    目标: 编译Apache Hadoop2.2.0在win7x64环境下的Eclipse插件 环境: win7x64家庭普通版 eclipse-jee-kepler-SR1-win32-x86_64.z ...

  2. The mell hall——坑爹

    The mell hall 题目描述 In HUST,there are always manystudents go to the mell hall at the same time as soo ...

  3. Context Switch and System Call

    How many Context Switches is “normal”? This depends very much on the type of application you run. If ...

  4. 计算机本科/硕士找offer的总结 节选

    在这样的目标定位下,我的求职历程从2006年10月8日开始,到2007年1月10日正式结束,一共持续了3个月的时间.整个过程可以分为三个阶段:第一阶段:2006年10月份 找工作刚刚开始的阶段,什么都 ...

  5. PHP获取当前页面完整的URL

    #测试网址: http://localhost/blog/testurl.php?id=5 //获取域名或主机地址 echo $_SERVER['HTTP_HOST']."<br> ...

  6. 理解cookie的path和domain属性(转)

    今天在做验证码时发现一个问题:A.B窗口都打开同一个页面,A先生成一个验证码,B再生成验证码,这时A所生成的验证码被B覆盖掉了.原因是使用了同名的cookie来存储验证码.一时找不到解决方法就参考了W ...

  7. HDU 1828 Picture(长方形的周长和)

    HDU 1828 Picture 题目链接 题意:给定n个矩形,输出矩形周长并 思路:利用线段树去维护,分别从4个方向扫一次,每次多一段的时候,就查询该段未被覆盖的区间长度,然后周长就加上这个长度,4 ...

  8. android贴士Toast

    转载请注明出处:http://blog.csdn.net/droyon/article/details/42009015 我们可以用androd提供toast控制,但在使用过程中,给我们发了很多Toa ...

  9. C++习题 复数类--重载运算符2+

    Description 定义一个复数类Complex,重载运算符"+",使之能用于复数的加法运算.参加运算的两个运算量可以都是类对象,也可以其中有一个是整数,顺序任意.例如,c1+ ...

  10. 自己定义actionbar

    android中的actionbar可提供自己定义view.详细是先写好自己定义view的布局,然后在代码中获取Actionbar对象.调用 setCustomView方法. 可是这样,它还是会显示前 ...