- 浏览: 648970 次
- 性别:
- 来自: 石家庄
文章分类
最新评论
-
abao1:
老贾 在安装IDEA的过程中,在激活步骤时,按如下操作即可: ...
IntelliJ IDEA 2016注册方法和注册码 -
bo_hai:
./usr/bin/java: symbol lookup ...
jmagick安装步骤 -
wxcking:
不错的, 收藏一下
JAVA使用POI生成Excel文件 -
zgyfh:
大哥,密码是多少啊?zgyfh@tom.com谢谢了!新手学习 ...
WPF做的必备示例 -
记忆无泪:
jiasongmao 写道你的邮箱是多少,我可以发源代码到邮箱 ...
WPF做的必备示例
本文章非原创,转载自:
作 者:Beniao
文章出处:http://beniao.cnblogs.com/ 或 http://www.cnblogs.com/
按照MEF的约定,任何一个类或者是接口的实现都可以通过[System.ComponentModel.Composition.Export] 属性将其他定义组合部件(Composable Parts),在任何需要导入组合部件的地方都可以通过在特定的组合部件对象属性上使用 [System.ComponentModel.Composition.Import ]实现部件的组合,两者之间通过契约(Contracts)进行通信,实际上这一步可以简单的理解为“依赖注入”,本质上就是对象的实例初始化过程。
我个人理解,凡是通过MEF的[ExportAttribute]标注的对象都可以理解为一个可进行组合的部件,包括对象和对象的属性、字段、方法、事件等;且该对象可以通过[ImportAttribute]进行导入。如下示例代码:
public class StringProvider { /// <summary> /// 定义导出部件--契约为“Message” /// </summary> [Export("Message")] public string Output { get { return "Hello World"; } } } public class Client { /// <summary> /// 导入指定契约的部件 /// </summary> [Import("Message")] public string Input { get; set; } public void Print() { Console.WriteLine(Input); } }
所谓的契约也就是一种约定,或者叫做一种规则。如上代码中就使用到了契约,在对象StringProvider中就定义了一个导出部件属性 (Output),并为其指定了通信契约为“Message”。这里的“Message”就是一种约定,既约定为在需要使用到这个属性的地方,都可以通过 [ImportAttribute]使用契约(Message)进行部件的导入。
接下来结合《Silverlight中使用CompositionInitializer宿主MEF 》一文中使用的日志记录的应用实例为基础来看看关于契约(Contracts)在较为复杂的部件中的的具体使用方法。假设定义了如下的接口与部件实现代码:
public interface ILogger { void WriteLog(string message); } [Export(typeof(ILogger))] public class TXTLogger : ILogger { public void WriteLog(string message) { MessageBox.Show("TXTLogger>>>>>" + message); } } [Export(typeof(ILogger))] public class DBLogger : ILogger { public void WriteLog(string message) { MessageBox.Show("DBLogger>>>>>" + message); } }
对于熟悉面向对象设计方法的人一眼就能明白,上面代码演示了一个接口具有多个实现的场景,仔细观察会发现在每个实现类上面都添加了 [ExportAttribute]将其标注为导出部件,并为其添加了通信契约,而且两个实现类的通信契约都是使用的接口(ILogger)的类型参数。
这里需要注意的是在进行导入的时候如果辨别到底是使用的哪一个实现呢?在MEF中提供了一个专门用于导入多个实现的特性 [System.ComponentModel.Composition.ImportManyAttribute],如上的日志实现示例就可以通过如下 的方式实现多部件导入。
[ImportMany] public IEnumerable<ILogger> Loggers { get; set; }
ImportManyAttribute特性可以将实现接口的所有实现全部组合起来。下面为使用[ImportMany]的完整示例代码:
namespace MEFTraining.CPC { public partial class MainPage : UserControl { [ImportMany] public IEnumerable<ILogger> Loggers { get; set; } public MainPage() { InitializeComponent(); CompositionInitializer.SatisfyImports(this); if (Loggers == null) { foreach (var logger in Loggers) { logger.WriteLog("Hello World"); } } } } public interface ILogger { void WriteLog(string message); } [Export(typeof(ILogger))] public class TXTLogger : ILogger { public void WriteLog(string message) { MessageBox.Show("TXTLogger>>>>>" + message); } } [Export(typeof(ILogger))] public class DBLogger : ILogger { public void WriteLog(string message) { MessageBox.Show("DBLogger>>>>>" + message); } } }
上面介绍了如何在相同的契约下获取所有导出部件的实例,在某种情况下或许我们就只直接指导需要使用那一种那个实现方式,那么是否可以通过直接 指定一个“契约名”就可以从多个实现中获取到指定的组合部件呢?答案是肯定的,接下来先看看在MEF中中对ExportAttribute和 ImportAttribute的定义,源代码如下:
public class ExportAttribute : Attribute { public ExportAttribute() : this((string)null, (Type)null){} public ExportAttribute(Type contractType) : this((string)null, contractType){} public ExportAttribute(string contractName) : this(contractName, (Type)null) { } public ExportAttribute(string contractName, Type contractType) { this.ContractName = contractName; this.ContractType = contractType; } public string ContractName { get; private set; } public Type ContractType { get; private set; } }
ImportAttribute同ExportAttribute一样提供了相同的重载构造函数,在将一个对象进行导出部件处理的时候可以直接通过ImportAttribute的属性给对象指定一个契约名,如本篇前面的日志组件的实现就可以修改为如下代码格式。
public interface ILogger { void WriteLog(string message); } [Export("TXT", typeof(ILogger))] public class TXTLogger : ILogger { public void WriteLog(string message) { MessageBox.Show("TXTLogger>>>>>" + message); } } [Export("DB", typeof(ILogger))] public class DBLogger : ILogger { public void WriteLog(string message) { MessageBox.Show("DBLogger>>>>>" + message); } }
通过为不同的导出部件指定了特定的契约名称,那么在装配部件的时候就可以通过契约名进行指定部件的装配并组合部件,为了方便调用可以提供一个服务类,将不同的实现通过不同的契约名装载组合起来以对系统提供一个统一的调用入口。以下为完整的示例代码:
public partial class MainPage : UserControl { /// <summary> /// 导入日志服务对象 /// </summary> [Import] public LogService Service { get; set; } public MainPage() { InitializeComponent(); CompositionInitializer.SatisfyImports(this); Service.DBLogger.WriteLog("Hello MEF"); Service.TXTLogger.WriteLog("Hello MEF"); } } /// <summary> /// 聚合不同的日志记录部件,通过MEF进行组合 /// </summary> [Export] public class LogService { /// <summary> /// 根据契约名进行部件的装配 /// </summary> [Import("TXT")] public ILogger TXTLogger { get; set; } [Import("DB")] public ILogger DBLogger { get; set; } } public interface ILogger { void WriteLog(string message); } [Export("TXT", typeof(ILogger))] public class TXTLogger : ILogger { public void WriteLog(string message) { MessageBox.Show("TXTLogger>>>>>" + message); } } [Export("DB", typeof(ILogger))] public class DBLogger : ILogger { public void WriteLog(string message) { MessageBox.Show("DBLogger>>>>>" + message); } }
发表评论
-
silvelright酷站
2011-03-22 18:47 775http://completit.com/# -
silverlight翻转代码
2011-03-13 18:46 1073using System; using System.Net ... -
silverlight独立存储示例
2011-03-07 17:17 1020void CreateDir(string dirNam ... -
silverlight SDK和toolit中控件英文如何转换为英文
2010-11-11 15:50 961解决方法: 设置 ... -
Silverlight4:网络地图服务
2010-10-16 11:01 1530Bing Maps与Google Earth一样 ... -
通过JS创建silverlight对象
2010-10-12 13:04 1601前言: 对于我们开发的silverlight应用来讲,有的时 ... -
silverlight childwindow源码
2010-09-18 21:17 1936<!-- // (c) Copyright Micro ... -
精彩的 Silverlight 开源项目
2010-08-18 14:32 2891Silverlight 物理模型 http://www.c ... -
MEF程序设计指南五:迟延(Lazy)加载导出部件(Export Part)与元数据(Metadata)
2010-08-12 10:34 898本文章非原创,转载自: 作 者:Beniao 文 ... -
MEF程序设计指南四:使用MEF声明导出(Exports)与导入(Imports)
2010-08-12 10:03 571本文章非原创,转载自: 作 者:Beniao 文 ... -
MEF程序设计指南二:Silverlight中使用CompositionInitializer宿主MEF
2010-08-12 09:24 823本系列文章非原创,转载自: 作 者:Beniao ... -
MEF程序设计指南一:在应用程序中宿主MEF
2010-08-12 09:17 986本系列文章非原创,转 ... -
silverlight应用程序库缓存
2010-08-10 14:22 1468应用程序库缓存可在用户重新访问网站时帮助改善启动性能。 ... -
Prism动态模块加载
2010-08-10 10:27 1549这篇介绍模块在silverlight的特殊应用. sil ... -
Silverlight中Json数据的转换方法(中文)
2010-08-04 11:36 1207[DataContract] public clas ... -
silverlight万花筒效果
2010-07-28 16:14 835见附件。 -
silverlight如何将颜色字符串转换为颜色
2010-07-02 10:42 1502public class ColorUtil { ... -
silverlight中Tab转Enter的实现方法
2010-06-04 17:38 1696silverlight项目中要求界面全键盘操作,并且在光标移动 ... -
在两个Silverlight应用间数据通信(包括与Flash通信)
2010-05-13 17:06 973声明:该博文转载自:http://daizhj.blog.51 ... -
silverlight和js相互调用
2010-05-13 16:56 1629步骤一:在silverlight后台代码类中声明被js调用的方 ...
相关推荐
在WPF中MEF的应用,有简单实例和代码,MEF是主程序
MEF白皮书中文版 .NET框架4.0 版本包括了支持面向组件编程的类。 这些称为组合基元的最底层的类代表了: ● 具有相互组合能力的组件; ● 支持丰富元数据的组件定义; ● 面向组件库的通用查询接口。 在...
MEF(Managed Extensibility Framework)简单实现
Mef demoMef demo
MEF框架在Silverlight中应用,MEF是微软的插件解决方案。
MEF框架源代码 MEF框架源代码 MEF框架源代码
这个代码介绍了mef与wcf整合的一个基础方案,通过mef实现动态和模块化管理wcf的一个基础实现思路。
这是目前metro ethernet 技术最权威的标准met,该文档是mef10.2
引导程序 MEF Autofac应用程序引导程序
MEF实例,MEF实例,MEF实例,MEF实例,MEF实例,MEF实例,MEF实例
MEF 让扩展不仅可在应用程序内重复使用,还可以跨程序重复使用。传统的 C/S 端开发,如果项目不是特别复杂,常规的开发模式还是可以应对的。但是一旦场景复杂度提升,一个小小业务功能的修改就需要更新整个客户端,...
MEF入门,适合架构师和设计师学习,不错的资料
托管扩展性框架(Managed Extensibility Framework,简称MEF),是微软.NET框架下为提高应用和组件复用...使用MEF能够使静态编译的.NET应用程序转换为动态组合,这将是创建可扩展应用、可扩展框架和应用扩展的好途径。
使用MEF能够使静态编译的.NET应用程序转换为动态组合,这将是创建可扩展应用、可扩展框架和应用扩展的好途径。它将做为.NET Framework 4.0的组成部分之一发布。现在,这个框架在.NET3.5中也可以运行。
一个简单的 Silverlight 4 应用程序(MEF+ MVVM+ WCF RIA Services)配套源代码及安装文件 本文是Weidong Shen先生在CodeProject上的文章源代码
WPF prism MEF 架构
MEF14,以太网交换机设备MEF认证必须
MEF9,认证测试规范,交换设备MEF认证必须.
MEF在AppDomain中演示在AppDomain中使用MEF并允许在应用程序运行时交换MEF零件。 这是我有关此主题的博客条目的源代码:和文章:
MEF框架整理学习内容