MEF初体验之十:部件重组
一些应用程序被设计成在运行时可以动态改变。例如,一个新的扩展被下载,或者因为其它的多种多样的原因其它的扩展变得不可用。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初体验之十:部件重组的更多相关文章
- MEF初体验之十二:Composition Batch
一个MEF容器实例是不可变的.如果catalog支持改变(像观察一个目录的改变)或是如果你的代码在运行时添加或移除部件,改变都可能发生.以前,你不得不作出改变并在组合容器上调用它的组合方法.在Prev ...
- MEF初体验之二:定义组合部件和契约
组合部件 在MEF中,一个组合部件就是一个组合单元,组合部件"出口"其它组合部件需要的服务并且从其它部件"进口"需要的服务.在MEF编程模型中,为了声明组合部件 ...
- MEF初体验之三:Exports声明
组合部件通过[ExportAttribute]声明exports.在MEF中,有这么几种成员可声明exports的方式:组合部件(类).字段.属性和方法.我们来看下ExportAttribute类的声 ...
- MEF初体验之九:部件生命周期
理解MEF容器中部件的生命周期及其含义是非常重要的.鉴于MEF重点在开放端应用程序,这将变得尤其重要的,一旦app ships和第三方扩展开始运行,作为应用程序的开发者将很好地控制这一系列的部件.生命 ...
- MEF初体验之七:Using Catalogs
MEF特性化编程模型的价值主张之一是通过catalogs动态发现部件的能力.Catalogs允许应用程序很容易地消费那些通过[Export]已经自我注册的exports. Assembly Catal ...
- MEF初体验之四:Imports声明
组合部件使用[System.ComponentModel.Composition.ImportAttribute]特性声明导入.与导出类似,也有几种成员支持,即为字段.属性和构造器参数.同样,我们也来 ...
- MEF初体验之八:过滤目录
当在使用子容器的时候,基于某些具体标准来过滤目录可能是重要的.例如,基于部件的创建策略来过滤是很常见的.下面的代码片段演示了如何构建这种特别方法: var catalog = new Assembly ...
- MEF初体验之五:Lazy Exports
在一个部件组合中,导入将触发一个部件或者多个部件的实例化,这些部件暴露了所需原请求部件的必要的导入.对于一些应用程序来说,延迟实例化-防止图结构下的递归组合-可能对于将创建一个长久复杂的开销很大而不必 ...
- MEF初体验之十一:查询组合容器
查询组合容器 组合容器暴露了几个get exports的重载方法和导出对象和对象集合.你需要注意下面的行为: 当请求单个对象实例时,如果未发现导出,一个异常将被抛出 当请求单个对象实例时,如果发现超过 ...
随机推荐
- Javascrpt 页面工具
/** * 笔者:DL * 时间:2014-3-19 * PagingTool模块提供最基本的.网页工具栏.和页面数据 回电话 可扩展性 分页工具栏介绍,和页面呈现的数据 * 主意 ...
- 第一章 andrid visdio 安装
第一章 andrid visdio 安装与环境搭建 一.Android Studio简介 Android Studio是Google新发布的Android应用程序开发环境,Android Stud ...
- Qt数据类型转换
把QString转换为double类型 方法1.QString str="123.45"; double val=str.toDouble(); //val=123.45 方法2. ...
- 局域网连接SQL Server数据库配置
首先要保证两台机器位于同一局域网内,然后打开配置工具→SQL Server配置管理器进行配置.将MSSQLSERVER的协议的TCP/IP的(IP1.IP2)TCPport改为1433,已启用改为是. ...
- 使用dom4j创建和解析xml
之前工作中用到了,相信写java的都会碰到xml,这里写了两个方法,创建和解析xml,废话不多说,直接上代码 package xml; import java.io.File; import java ...
- ASP.NET回车提交事务
浅析ASP.NET回车提交事件[转] ASP.NET回车提交事件其实说到底并不是ASP.NET 的编程问题,却是关于html form 中的submit 按钮就是如何规划的具体讨论. 也可归于ASP. ...
- cocos2d-x3.0rc 版 设置模拟器窗体大小
由于刚接触这职业时间不是非常长.也是第一次写博客,假设有错误的地方还请大神们指出,开通这博客目的非常easy相互学习和讨论(更重要的是记录工作中学到的东西以方便以后自己查阅) 先后參与过两个项目.只是 ...
- linux文件打开模式
文件打开 int open(const char *pathname, int flags, mode_t mode); 普通方式(Canonical mode) flags中没有设置O_SYN ...
- cocos2dx --- Widget 载入中 CCNode
如果说. Widget 有addChild() 与 addNode() 两个方法. 如今我要载入一个粒子特效进去,下图: Widget* layout = dynamic_cast<Wid ...
- CareerCup它1.8 串移包括问题
[称号] 原文: 1.8 Assume you have a method isSubstring which checks if one word is a substring of another ...