原文地址: http://www.cnblogs.com/xiaokang088/archive/2012/02/21/2361631.html

MEF 的精髓在于插件式开发,方便扩展。

例如,应用程序的日志输出到文本,后来想改为输出到数据库,按照传统的办法,需要替换项目,删除原有的引用,增加新的引用;如果使用MEF,直接用新的dll替换原来的dll,即可搞定,这就是MEF的魅力。

下面就用简单的例子来实现上述的需求。

1. 建立一个解决方案,然后增加如下的几个项目

DBlog 输出日志到数据库的实现

TextLog 输出日志到文本的实现

ILog 输出日志的接口,调用方和实现者的中间桥梁

MEFConsoleHost 控制台应用程序,模拟实用场合

MEFWPFHost WPF 应用程序,模拟实用场合

2. 先定义接口ILog,非常简单,就一个方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ILog
{
public interface ILogService
{
void Log(string content);
}
}

3. 输出到文本的实现TextLog

首先添加引用:引用刚才添加的接口Ilog 和System.ComponentModel.Composition

然后增加类TextLogService.cs,继承接口,并实现方法。

注意 类和方法都Public。

最后定义导出[Export(typeof(ILog.ILogService))]

这个是最主要的,和普通的类库区别也在这里

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.ComponentModel.Composition; namespace TextLog
{
[Export(typeof(ILog.ILogService))]
public class TextLogService : ILog.ILogService
{
public void Log(string content)
{
Console.WriteLine("TextLog:" + content); System.Diagnostics.TextWriterTraceListener TraceListener = new System.Diagnostics.TextWriterTraceListener(@"d:/debug.txt");
System.Diagnostics.Debug.Listeners.Add(TraceListener);
System.Diagnostics.Debug.Write(System.DateTime.Now.ToString()+" ");
Debug.Write("TextLog:" + content);
Debug.WriteLine("~~");
TraceListener.Flush();
}
}
}

4. 输出到数据库的实现DBLog,实现方法同上例,输出日志的时候区分一下。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.ComponentModel.Composition; namespace DBLog
{
[Export(typeof(ILog.ILogService))]
public class DBLogService: ILog.ILogService
{
public void Log(string content)
{
Console.WriteLine("DBLog:" + content); System.Diagnostics.TextWriterTraceListener TraceListener = new System.Diagnostics.TextWriterTraceListener(@"d:/debug.txt");
System.Diagnostics.Debug.Listeners.Add(TraceListener);
System.Diagnostics.Debug.Write(System.DateTime.Now.ToString()+" ");
Debug.Write("DBLog:" + content);
Debug.WriteLine("");
TraceListener.Flush();
}
}
}

5. 调用方MEFConsoleHost, 这个也需要增加两个引用,

ILog 和System.ComponentModel.Composition

主程序代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting; namespace MEFConsoleHost
{
class Program
{
[Import(typeof(ILog.ILogService))]
public ILog.ILogService CurrentLogService { get; set; } static void Main(string[] args)
{
Program pro = new Program();
pro.run();
} private void run()
{
//var catalog = new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory,"DbLog.dll");
var catalog = new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory, "TextLog.dll"); var container = new CompositionContainer(catalog);
container.ComposeParts(this); CurrentLogService.Log("*MEF Log Test Pass*");
Console.Read();
}
}
}

注意两个地方

a. 导入声明

[Import(typeof(ILogService))]
public ILogService CurrentLogService { get; set; }

用接口来定义实例,然后增加导入声明,和导出的相互对应

b. 建立Catalog和Container

var catalog = new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory, "TextLog.dll");
var container = new CompositionContainer(catalog);
container.ComposeParts(this);

6. 把所有项目的输出都指定到同一个目录,也就说让dll和exe在同一目录,运行控制台程序,输出

TextLog: MEF Log Test Pass

7.如果我们要输出到数据库,把上面的catalog那一句改成

var catalog = new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory,"DBLog.dll");

如果不想这么麻烦,这个目录里面只放DBLog.dll 或者TextLog.dll ,然后把上面那句改为:

var catalog = new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory);

照样可以用。

如果两个都在,还这么搞,那不行的,因为就定义了一个实例,同目录有两个dll。

MEF简单示例的更多相关文章

  1. Linux下的C Socket编程 -- server端的简单示例

    Linux下的C Socket编程(三) server端的简单示例 经过前面的client端的学习,我们已经知道了如何创建socket,所以接下来就是去绑定他到具体的一个端口上面去. 绑定socket ...

  2. C# 构建XML(简单示例)

    C# 构建XML的简单示例: var pars = new Dictionary<string, string> { {"url","https://www. ...

  3. 根据juery CSS点击一个标签弹出一个遮罩层的简单示例

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  4. ACEXML解析XML文件——简单示例程序

    掌握了ACMXML库解析XML文件的方法后,下面来实现一个比较完整的程序. 定义基本结构 xml文件格式如下 <?xml version="1.0"?> <roo ...

  5. demo工程的清单文件及activity中api代码简单示例

    第一步注册一个账户,并创建一个应用.获取app ID与 app Key. 第二步下载sdk 第三步新建工程,修改清单文件,导入相关的sdk文件及调用相应的api搞定. 3.1 修改清单文件,主要是加入 ...

  6. spring-servlet.xml简单示例

    spring-servlet.xml简单示例 某个项目中的spring-servlet.xml 记下来以后研究用 <!-- springMVC简单配置 --> <?xml versi ...

  7. SignalR 简单示例

    一.什么是 SignalR ASP.NET SignalR is a library for ASP.NET developers that simplifies the process of add ...

  8. Web API 简单示例

    一.RESTful和Web API Representational State Transfer (REST) is a software architecture style consisting ...

  9. XML引入多scheme文件约束简单示例

    XML引入多scheme文件约束简单示例,用company.xsd和department.xsd来约束company.xml: company.xsd <?xml version="1 ...

随机推荐

  1. jsp不能引用js,cs等解决办法

    最近项目中使用到Spring3,在感叹Spring3注解配置清爽的同时竟然出现了这个不和谐的事情,实在无法忍受 问题:部署项目后程序加载或用浏览器访问时出现类似的警告,2011-01-19 10:52 ...

  2. 《C标准库》——之<stddef.h>

    <stddef.h>,顾名思义,就是标准定义.C语言里这个标准库里定义了一些类型,和宏定义. <stddef.h>的内容: 类型: ptrdiff_t : 是两个指针相减的结果 ...

  3. 解决Android时时更新listview数组越界问题

    时时更新数据一般出现在金融.股票行业对数据的准确性要求极高情况下使用. 先来看看下面一段代码, public class MainActivity extends Activity { private ...

  4. android中ListView控件&&onItemClick事件中获取listView传递的数据

    http://blog.csdn.net/aben_2005/article/details/6592205 本文转载自:android中ListView控件&&onItemClick ...

  5. java日期类型转换总结date timestamp calendar string

    用Timestamp来记录日期时间还是很方便的,但有时候显示的时候是不需要小数位后面的毫秒的,这样就需要在转换为String时重新定义格式.         Timestamp转化为String: S ...

  6. 5-1 源码包与RPM包的区别

    1.区别 <1>安装之前的区别:概念上的不同(是否开源等,更多请点我) <2>安装之后的区别:安装位置不同 2.RPM包安装位置 <1>是安装在默认位置中,但不是确 ...

  7. codevs3872 邮递员送信(SPFA)

    邮递员送信 时间限制: 1 Sec  内存限制: 64 MB提交: 10  解决: 5[提交][状态][讨论版] 题目描述 有一个邮递员要送东西,邮局在节点1.他总共要送N-1样东西,其目的地分别是2 ...

  8. JSBinding + SharpKit / 原理篇:内存管理与垃圾回收

    C# 和 JS 都有垃圾回收机制,需要保证 2 者能够分工协作. 类对象 类在C#中是引用类型.我们在 C# 中维护了2个map,保存 C# 对象和 JS 对象的一一对应关系. 举一个例子,看以下代码 ...

  9. PostgreSQL and bloat

    The bucardo project has released its nagios plugins for PostgreSQL and we can extract from them this ...

  10. 转载:javascript 拖拽排序,简洁示例备忘

    转载自:http://blog.csdn.net/wang4978/article/details/6721157 <html> <head> <title>拖动行 ...