MEF初体验之三:Exports声明
组合部件通过[ExportAttribute]声明exports。在MEF中,有这么几种成员可声明exports的方式:组合部件(类)、字段、属性和方法。我们来看下ExportAttribute类的声明:
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method
| AttributeTargets.Class, AllowMultiple=true, Inherited=false)]
public class ExportAttribute : Attribute
{ }
果然,支持这四种成员,另外,在同一个目标上可应用多次该特性但是它不支持继承,如果想继承则需使用ExportAttribute的派生类InheritedExportAttribute来实现。
组合部件导出
组合部件导出被用在当需要导出它自己的时候。在前面的例子中,我们使用的都是这种方式。
[Export(typeof(IMessageSender))]
class EmailSender : IMessageSender
{
public void Send(string msg)
{
Console.WriteLine("Email Sent:"+msg);
}
}
这里,我们需要将EmailSender部件自身导出,其实就是类级别的导出。
属性导出
组合部件也可以导出属性。属性导出有这么几个优点:
- 它允许导出像核心的CLR类型这样的密封类,或者是其它第三方类
- 它允许将导出创建方式和导出解耦。例如,导出运行时为你创建的已经存在的HttpContext部件
- 它允许在相同的组合部件中有一些相关的exports,例如一个DefaultSendersRegistry组合部件默认有一系列senders属性导出
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.Composition.Hosting; namespace ExportsDeclaring
{
class Program
{
[Import]
public UsesTimeout UsesTimeout { get; set; }
static void Main(string[] args)
{
Program p = new Program();
p.Compose();
Console.WriteLine(p.UsesTimeout.Timeout);
Console.ReadKey();
}
void Compose()
{
var container = new CompositionContainer();
container.ComposeParts(this, new UsesTimeout(),new Configuration());
}
}
public class Configuration
{
[Export("Timeout")]
public int Timeout
{
get { return int.Parse(ConfigurationManager.AppSettings["Timeout"]); }
}
}
[Export]
public class UsesTimeout
{
[Import("Timeout")]
public int Timeout { get; set; }
}
}
在上面的代码之前,需要先在配置文件中配置key为Timeout的AppSetting,例如:<add key="Timeout" value="5000"/>。
输出为:

方法导出
方法导出是用在一个部件要将它的方法导出的地方。通过在导出契约中指定委托的方式来导出方法。方法导出有下面的几点好处:
- 它允许对于要导出的方法进行细粒度的控制。例如,一个规则引擎可能倒入一系列可插拔的方法导出部件。
- 它屏蔽了调用者对于类型的了解。
- 它可以由代码生成器生成,你不需要处理其它的导出部件。
注意:由于框架的限制,方法导出最多不能超过四个参数。
在下面的例子中,MessageSender类将它的Send方法导出为一个Action<string>委托,这个Processor导入了这个相同的委托。
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace ExportsDeclaring
{
class Example
{
[Import]
public Processor Processor { get; set; }
static void Main()
{
Example e = new Example();
e.Compose();
e.Processor.Send();
Console.ReadKey();
}
void Compose()
{
var container = new CompositionContainer();
container.ComposeParts(this, new Processor(), new MessageSender());
}
}
public class MessageSender
{
[Export(typeof(Action<string>))]
public void Send(string msg)
{
Console.WriteLine(msg);
}
}
[Export]
public class Processor
{
[Import(typeof(Action<string>))]
public Action<string> MessageSender { get; set; } public void Send()
{
MessageSender("Processed");
}
}
}
输出为:

你也可以使用一个简单的字符串契约来导入导出。但是,当进行方法导出时,你必须得提供一个类型或者字符串七月名称,而不能留空。
导出继承
MEF支持在一个基类或者接口中定义的导出将自动地被它的实现类继承的能力。这对于与那些想要利用MEF来发现而不是要求修改已有的客户代码的传统框架来说是很理想的。为了提供这种能力需要使用[System.ComponentModel.Composition.InheritedExportAttribute]。例如下面的ILogger接口有一个[InheritedExport],Logger实现了该接口,因此自动地导出了ILogger。
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace ExportsDeclaring
{
class Example1
{
[Import]
public ILogger Logger { get; set; }
static void Main()
{
Example1 e = new Example1();
e.Compose();
e.Logger.Log("Logging");
Console.ReadKey();
}
void Compose()
{
var container = new CompositionContainer();
container.ComposeParts(this, new Logger());
}
}
[InheritedExport]
public interface ILogger
{
void Log(string msg);
}
public class Logger : ILogger
{
public void Log(string msg)
{
Console.WriteLine(msg);
}
} }
发现非公有的组合部件
MEF支持公有和非公有部件的发现。你不需要做任何事情来启用该行为。请注意:在并不完全受信任的环境中(包括sliverlight),非公有的组合将不被支持。
MEF初体验之三:Exports声明的更多相关文章
- MEF初体验之五:Lazy Exports
在一个部件组合中,导入将触发一个部件或者多个部件的实例化,这些部件暴露了所需原请求部件的必要的导入.对于一些应用程序来说,延迟实例化-防止图结构下的递归组合-可能对于将创建一个长久复杂的开销很大而不必 ...
- MEF初体验之四:Imports声明
组合部件使用[System.ComponentModel.Composition.ImportAttribute]特性声明导入.与导出类似,也有几种成员支持,即为字段.属性和构造器参数.同样,我们也来 ...
- MEF初体验之二:定义组合部件和契约
组合部件 在MEF中,一个组合部件就是一个组合单元,组合部件"出口"其它组合部件需要的服务并且从其它部件"进口"需要的服务.在MEF编程模型中,为了声明组合部件 ...
- MEF初体验之七:Using Catalogs
MEF特性化编程模型的价值主张之一是通过catalogs动态发现部件的能力.Catalogs允许应用程序很容易地消费那些通过[Export]已经自我注册的exports. Assembly Catal ...
- MEF初体验之一:在应用程序宿主MEF
在MEF出现以前,其实微软已经发布了一个类似的框架,叫MAF(Managed Add-in Framework),它旨在使应用程序孤立和更好的管理扩展,而MEF更关心的是可发现性.扩展性和轻便性,后者 ...
- MEF初体验之十二:Composition Batch
一个MEF容器实例是不可变的.如果catalog支持改变(像观察一个目录的改变)或是如果你的代码在运行时添加或移除部件,改变都可能发生.以前,你不得不作出改变并在组合容器上调用它的组合方法.在Prev ...
- MEF初体验之十一:查询组合容器
查询组合容器 组合容器暴露了几个get exports的重载方法和导出对象和对象集合.你需要注意下面的行为: 当请求单个对象实例时,如果未发现导出,一个异常将被抛出 当请求单个对象实例时,如果发现超过 ...
- MEF初体验之十:部件重组
一些应用程序被设计成在运行时可以动态改变.例如,一个新的扩展被下载,或者因为其它的多种多样的原因其它的扩展变得不可用.MEF处理这些多样的场景是依赖我们称作重组的功能来实现的,它可已在最初的组合后改变 ...
- MEF初体验之九:部件生命周期
理解MEF容器中部件的生命周期及其含义是非常重要的.鉴于MEF重点在开放端应用程序,这将变得尤其重要的,一旦app ships和第三方扩展开始运行,作为应用程序的开发者将很好地控制这一系列的部件.生命 ...
随机推荐
- Android基于cordova3.3插件开发
最近的工作项目,需要使用cordova插件开发,详细Cordova角色,不会走,你可以去百度自身OK该,直接启动.详细过程,我有一个小Demo解说提前进行. 还只是接触,东西太理论基础,我也不太清楚, ...
- jQuery的理论基础
概述 jQuery是用JavaScript语言编写的函数库,我们用时,可以直接调用jQuery中相应的函数,对于JavaScript的理解,前面的博客已经介绍过了,在这里只说一下函数的作用,也可以说为 ...
- Solaris 10下使用Python3
通常在Solaris 10上仅仅能使用Python2.x. 假设使用Python3的话,一种就是http://www.sunfreeware.com获取可用的二进制版本号.只是眼下这个站点已经不提供免 ...
- C 和 C++ 的速度相差多少,你知道吗?
有谁清楚这个事实吗 ? 网络游戏速度至关重要, 是游戏质量的唯一标准, 尤其是即时格斗, 相差几毫秒都会影响用户体验 ! 哪怕就是 5% 的效率损失,也是 差之毫厘,失之千里, 游戏的速度是程序语言天 ...
- cocos2d-x3.0数据结构
1.cocos2d::Vector 1.头报价"CCVector.h"头文件. 2.保存的数据类型必须是cocos2d::Ref的子类. 3.实现是动态加入数据集合即链表.主要的使 ...
- Sencha Architect 2 的使用
俗话说的好, 工欲善其事必先利其器, 用Sencha开发的语言, 自己可能不太熟悉, 写出来很麻烦, 于是给大家介绍一个工具. 启动程序第一个界面: 单击第一个Go按钮, 创建一个项目.进入以后, 单 ...
- 北邮iptv用WindowsMediaplayer打不开的解决的方法
前言:之前我的iptv能够用,可是有次我安装了realplayer,它就偷偷把iptv文件的默认打开方式给篡改了,卸载了 realplayer之后,iptv不能直接用 ...
- [MSSQL]最小公约数
[摘要]一个朋友在展BOM的时候有这种需求,两列字段(数值):A ,B A=用量,B=底数,组成用量=用量/底数.A/B,若能被整除,显示整除的结果,若不能整除显示分数形式A/B(分数形式要是约分 ...
- Directx11学习笔记【十六】 光照模型的实现
本文由zhangbaochong原创,转载请注明出处http://www.cnblogs.com/zhangbaochong/p/5579289.html 在之前的场景绘制中我们都是给每个顶点指定了单 ...
- WPF技术触屏上的应用系列(六): 视觉冲击、超炫系统主界面、系统入口效果实现
原文:WPF技术触屏上的应用系列(六): 视觉冲击.超炫系统主界面.系统入口效果实现 去年某客户单位要做个大屏触屏应用,要对档案资源进行展示之用.客户端是Window7操作系统,54寸大屏电脑电视一体 ...