MEF学习系列笔记系列(1)
2014-01-07 10:54
141 查看
最近,年底项目开始有点空闲,跟我们对接接口的那边正在开发,而我们这边开发完毕,但是对方接口不稳定而且很不成熟,所以暂时停止对接,等稳定再进行对接,本日在对接接口方面经验比较足,所以敢于拿出时间去学习新的知识,觉得MEF以前没怎么接触,最近想提升一下,所以就写呢这篇文章,供大家学习,由于这方面经验有限,有什么不足,望大家指出,我的Email为:wangyonghua_net@126.com.
MEF参考资料主要来源:
王春明- http://www.cnblogs.com/wangchunming/archive/2012/04/23/2467128.html,
一个人在北京- http://www.cnblogs.com/content/archive/2013/05/31/3111156.html
以前觉得自己懂就可以啦,没有做像样的总结,给大家分享,现在我觉得写博客也要认真的对待,把实际遇到的问题,自己的理解分享给大家,望与大家交流,相互学习.
应用程序里托管MEF
应用程序里托管MEF包括创建一个CompositionContainer实例,添加组成部件,包括宿主本身,然后组合。
下面是组合的步骤:
创建一个宿主类,下面的例子里我们使用控制台应用程序,所以宿主是Program类。
添加System.ComponentModel.Composition的引用;
在头部添加using System.ComponentModel.Composition;
添加一个Compose()方法,用来创建一个container实例,并跟宿主组合;
添加一个Run()方法,用来执行Compose();
在Main()里实例化宿主类。
注意:对于ASP.NET和WPF应用程序,宿主类在运行时就已经实例化,所以这个步骤没有必要。
给容器添加部件。在MEF有几个方法可以做到这个。一个方法是直接添加目前的组成部件实例,另一个更常用的方法是通过使用目录,这个我们在下面的章节会提到.
直接添加部件到容器
在Compose()方法里通过重载方法ComposeParts()手动添加每个组成部件。下面的例子里一个EmailSender的实例和当前要导入的Program实例一起添加到容器。
用数据集目录(AssemblyCatalog)添加到容器(container)
通过使用这个目录,container句柄会自动添加部件,而不是显式的添加。为了实现这个,在Compose()里创建一个目录catalog。然后从目录创建一个解析器,把它传给container的构造函。
下面的例子是一个用正在执行的程序集创建的AssemblyCatalog传进构造函数。我们没有添加EmailSender实例因为它会在当前程序集的目录被发现。
Assembly.GetExecutingAssembly()Gets the assembly that contains the code that is currently executing.
经过上面的步骤之后,代码应该是这样:
执行上面的代码,应用程序会用它的IMessageSender导入来组装,之后Send()会被执行,结果会输出“Message Sent”
![](https://img-blog.csdn.net/20140107105915687?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2FuZ3lvbmdodWFfbmV0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
同时我也做呢另外一个控制台项目,宿主代码代码如下:
结果运行如下:
MEF参考资料主要来源:
王春明- http://www.cnblogs.com/wangchunming/archive/2012/04/23/2467128.html,
一个人在北京- http://www.cnblogs.com/content/archive/2013/05/31/3111156.html
以前觉得自己懂就可以啦,没有做像样的总结,给大家分享,现在我觉得写博客也要认真的对待,把实际遇到的问题,自己的理解分享给大家,望与大家交流,相互学习.
应用程序里托管MEF
应用程序里托管MEF包括创建一个CompositionContainer实例,添加组成部件,包括宿主本身,然后组合。
下面是组合的步骤:
创建一个宿主类,下面的例子里我们使用控制台应用程序,所以宿主是Program类。
添加System.ComponentModel.Composition的引用;
在头部添加using System.ComponentModel.Composition;
添加一个Compose()方法,用来创建一个container实例,并跟宿主组合;
添加一个Run()方法,用来执行Compose();
在Main()里实例化宿主类。
注意:对于ASP.NET和WPF应用程序,宿主类在运行时就已经实例化,所以这个步骤没有必要。
using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; using System.Reflection; using System; public class Program { public static void Main(string[] args) { Program p = new Program(); p.Run(); } public void Run() { Compose(); } private void Compose() { var container = new CompositionContainer(); container.ComposeParts(this); } }定义一个或多个导出(Export)用于给宿主导入(Import)。下面的代码,我们会定义一个IMessageSender接口,我们还会定义一个EmailSender组合部件,用来导出一个IMessageSender,这得通过声明 [System.ComponentModel.Composition.Export] 属性来实现:
public interface IMessageSender { void Send(string message); } [Export(typeof(IMessageSender))] public class EmailSender : IMessageSender { public void Send(string message) { Console.WriteLine(message); } }通过使用[System.ComponentModel.Composition.Import]修饰的属性,使每个导入将特性添加到宿主类。下面的例子是一个IMessageSender的导入将特性添加给Program类:
[Import] public IMessageSender MessageSender { get; set; }
给容器添加部件。在MEF有几个方法可以做到这个。一个方法是直接添加目前的组成部件实例,另一个更常用的方法是通过使用目录,这个我们在下面的章节会提到.
直接添加部件到容器
在Compose()方法里通过重载方法ComposeParts()手动添加每个组成部件。下面的例子里一个EmailSender的实例和当前要导入的Program实例一起添加到容器。
private void Compose() { var container = new CompositionContainer(); container.ComposeParts(this, new EmailSender()); }
用数据集目录(AssemblyCatalog)添加到容器(container)
通过使用这个目录,container句柄会自动添加部件,而不是显式的添加。为了实现这个,在Compose()里创建一个目录catalog。然后从目录创建一个解析器,把它传给container的构造函。
下面的例子是一个用正在执行的程序集创建的AssemblyCatalog传进构造函数。我们没有添加EmailSender实例因为它会在当前程序集的目录被发现。
private void Compose() { var catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()); var container = new CompositionContainer(catalog); container.ComposeParts(this); }
Assembly.GetExecutingAssembly()Gets the assembly that contains the code that is currently executing.
经过上面的步骤之后,代码应该是这样:
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
using System;
public class Program
{
[Import]
public IMessageSender MessageSender { get; set; }
public static void Main(string[] args)
{
Program p = new Program();
p.Run();
}
public void Run()
{
Compose();
MessageSender.Send("Message Sent");
}
private void Compose()
{
AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
}
public interface IMessageSender { void Send(string message); } [Export(typeof(IMessageSender))] public class EmailSender : IMessageSender { public void Send(string message) { Console.WriteLine(message); } }
执行上面的代码,应用程序会用它的IMessageSender导入来组装,之后Send()会被执行,结果会输出“Message Sent”
同时我也做呢另外一个控制台项目,宿主代码代码如下:
class Program { [ImportMany] public ILogger[] Loggers { get; set; } /// <summary> ///下面的代码说明如何启动在MEF组成过程。 ///下面的步骤用于静态构造函数: ///创建目录 (告诉MEF寻找部件 ) ///创建容器 (主机),并交给目录 。 ///容器调用Compose方法。 ///最后一步是从容器中获得logger /// </summary> /// <param name="args"></param> static void Main(string[] args) { var p = new Program(); var assemblyCatalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()); var container = new CompositionContainer(assemblyCatalog); container.ComposeParts(p); foreach (var logger in p.Loggers) { logger.Write("写日志"); } Console.Read(); } }部件与契约:
public interface ILogger { void Write(string message); }
/// <summary> /// 下面的代码是使用导出属性的部分装饰 ///要求为ILogger契约。 /// </summary> [Export(typeof(ILogger))] public class ConsoleLogger : ILogger { void ILogger.Write(string message) { Console.WriteLine(message); } } [Export(typeof(ILogger))] public class DebugLogger : ILogger { void ILogger.Write(string message) { Debug.WriteLine(message); } } [Export(typeof(ILogger))] public class EventLogLogger : ILogger { void ILogger.Write(string message) { EventLog.WriteEntry("MEFSample", message); } }
结果运行如下:
相关文章推荐
- MEF学习系列笔记系列(1)
- MEF学习系列笔记系列(1)
- android Fragment系列学习笔记之六
- Android学习系列笔记(二)
- 网易云课堂Java进阶学习笔记系列01 -- 第3周 对象容器
- Java中Annotation(注释)系列学习笔记(4)
- Opencv2系列学习笔记8(图像滤波)
- J2EE系列之MyBatis学习笔记(八)-- 杂项
- Sharepoint学习笔记—习题系列--70-573习题解析 -(Q111-Q114)
- 【非参数贝叶斯学习系列】Beta Distribution 学习笔记
- Deep Learning(深度学习)学习笔记整理系列之(六)
- FreeMarker系列学习笔记(2)
- 【Java反射学习笔记系列之jdk动态代理】静态代理和动态代理的区别以及动态代理的作用和实现
- 【ajax ASP.NET AJAX入门系列(1):概述】学习笔记
- 【达内C++学习培训学习笔记系列】C语言之三循环语句和数组
- google测试之道学习笔记系列(一)
- 自学Java系列 笔记5 Java学习之Java中增强型for循环的样例和解释
- (Java2D 学习笔记系列) (一)一个简单的图像填充实例及其分析理解
- 关于Maven学习笔记系列的声明
- J2EE系列之SpringMVC学习笔记(二)--SpringMVC控制器