前面一个博客:也来学学插件式开发中很多朋友留言说可以用MEF来实现。于是我就试着用MEF实现了一下。

步骤和上一篇差不多,只是加载插件的方式有所不同。这只是一个自己的示例程序,肯定有很多不足之处,欢迎拍砖。

MEF如何工作?

MEF主要是通过Import与Export特性来定义导入与导出部件。程序在运行的时候会将具有相同接口的导出的实例化,赋给导入。

MEF程序设计指南一:在应用程序中宿主MEF这篇文章有一个简单的MEF例子,大家可以参考一下。

所以,在这里,插件就是导出,我们在程序中要定义具有和插件相同接口的导入。

但是这里有一个问题,一般的导入与导出是一对一的,但我们的工具箱中和插件的关系明显是一对多的怎么办?

没问题,MEF对于这种情况可以将导入声明为ImportMany,这样就支持一个导入对应多个导出了。

关于ImportMany可参见:http://msdn.microsoft.com/en-us/library/dd460648.aspx#further_imports_and_importmany

因此这里,我用ImportMany来定义一个集合来保存插件:

        [ImportMany]
public IEnumerable<Iplugin> plugins;

如何让MEF发现插件?

我们用反射的时候是将插件放置在一个固定的目录中,然后再去扫描这个目录来发现插件,在MEF中如何来发现插件呢?

MEF提供三种方式发现部件:

  1. AssemblyCatalog 在当前程序集发现部件。
  2. DirectoryCatalog 在指定的目录发现部件。
  3. DeploymentCatalog 在指定的XAP文件中发现部件(用于silverlight)

可以看到,我们也可以将插件放在统一的目录让MEF去检索发现。

使用MEF

使用MEF的时候,首先要初始化MEF的组合容器对象:CompositionContainer,所以在窗体加载的时候要做好初始化工作。

        public ToolBox()
{
InitializeComponent();
Init();
}
private CompositionContainer _container; private void Init()
{
//An aggregate catalog that combines multiple catalogs
var catalog = new AggregateCatalog();
//设置目录
catalog.Catalogs.Add(new DirectoryCatalog(Application.StartupPath + "\\plugin\\")); //Create the CompositionContainer with the parts in the catalog
_container = new CompositionContainer(catalog); //Fill the imports of this object
try
{
this._container.ComposeParts(this);
}
catch (CompositionException compositionException)
{
Console.WriteLine(compositionException.ToString());
}
}

接着就是发现插件后的显示工作了:

        private void ToolBox_Load(object sender, EventArgs e)
{
InitPlugin();
} [ImportMany]
public IEnumerable<Iplugin> plugins; public void InitPlugin()
{
foreach (Iplugin plugin in plugins)
{
InitModule(plugin);
}
}

增加插件

我们来新增一个插件试试。新建一个类库项目,再增加一个Window窗体,拉一个PictureBox,显示一张图片。主要的工作是我们要定义导出:Export

   [Export(typeof(PluginMain.Interface.Iplugin))]
public class App:PluginMain.Interface.Iplugin
{
public System.Windows.Forms.Form MainForm
{
get { return new Picture(); }
} public System.Drawing.Image ModulePicture
{
get { return null; }
}
}

将生成的.DLL放在plugin目录中。生成后效果如图:

示例代码下载:点我

参考资料:【.Net平台下插件开发】-MEF与MAF初步调研

《MEF程序设计指南》博文汇总

Managed Extensibility Framework (MEF)

如果我的文章对你有帮助,就点一下推荐吧.(*^__^*)

也来学学插件式开发续-利用MEF的更多相关文章

  1. C#学习笔记-----基于AppDomain的"插件式"开发

    很多时候,我们都想使用(开发)USB式(热插拔)的应用,例如,开发一个WinForm应用,并且这个WinForm应用能允许开发人员定制扩展插件,又例如,我们可能维护着一个WinService管理系统, ...

  2. 基于AppDomain的"插件式"开发

    很多时候,我们都想使用(开发)USB式(热插拔)的应用,例如,开发一个WinForm应用,并且这个WinForm应用能允许开发人员定制扩展插件,又例如,我们可能维护着一个WinService管理系统, ...

  3. MEF 插件式开发 - 小试牛刀

    原文:MEF 插件式开发 - 小试牛刀 目录 MEF 简介 实践出真知 面向接口编程 控制反转(IOC) 构建入门级 MEF 相关参考 MEF 简介 Managed Extensibility Fra ...

  4. ctkPlugin插件系统实现项目插件式开发

    插件式开发体会: 自开始写[大话QT]系列就开始接触渲染客户端的开发,说是开发不如更多的说是维护以及重构,在接手这块的东西之前自己还有点犹豫,因为之前我一直认为客户端嘛,没什么技术含量,总是想做比较有 ...

  5. JQuery的插件式开发

    如果你只会JQuery的插件式开发, 那么你可以进来看看? 对于JQuery的学习,已经有3年多的时间了,直到去年与我的组长一起做项目,看到他写的JS,确实特别漂亮,有时甚至还看不太懂, 我才发现其实 ...

  6. MVC 插件式开发

    MVC 插件式开发 在开发一个OA系统是,我们可能遇到 A模块. B模块 .C模块,这也模块组成一个完整的系统,买给客服.现在又有一个客服要我们做一个OA系统,唉我们发现,跟上一个OA系统差不多,但没 ...

  7. .NET MVC 简单的插件式开发

    插件式开发的优势 1.提高软件的复用度 2.提高软件开发的并行性 3.缩短软件的研发周期.节约研发成本,带给程序开发人员更多的灵活性,产品在软件发布以后还可以添加新的插件和完善已有的功能. 4.方便软 ...

  8. MEF 插件式开发 - WPF 初体验

    原文:MEF 插件式开发 - WPF 初体验 目录 MEF 在 WPF 中的简单应用 加载插件 获取元数据 依赖注入 总结 MEF 在 WPF 中的简单应用 MEF 的开发模式主要适用于插件化的业务场 ...

  9. 从零开始实现ASP.NET Core MVC的插件式开发(一) - 使用ApplicationPart动态加载控制器和视图

    标题:从零开始实现ASP.NET Core MVC的插件式开发(一) - 使用Application Part动态加载控制器和视图 作者:Lamond Lu 地址:http://www.cnblogs ...

随机推荐

  1. mysqldump与source

    mysqldump示例 mysqldump --default-character-set=utf8 -d --opt -hlocalhost -uroot -p123456 --where=&quo ...

  2. C语言:自定义一个查找字串的功能函数,类似于<string.h>中的strstr()

    //自定义一个字符串字串查找标准库函数strstr() #include<stdio.h> #include<string.h> char* myStrstr(char *st ...

  3. Objective-C:继承、分类(Category、extension)、协议(protocol),个人理解,仅供参考

    总结:继承.分类(Category.extension).协议(protocol)   一.继承: (1)特点: 继承多用于一般父类中的方法功能比较齐全,子类从父类继承过来使用,可以省略很多重复的代码 ...

  4. Informatica 常用组件Source Qualifier之九 创建SQ转换

    可以配置 Designer 在您将源拖到映射中时默认创建源限定符转换,您也可以手动创建源限定符转换. 默认创建源限定符转换 可以配置 Designer 在您将源拖到映射中时自动创建一个源限定符转换. ...

  5. CSS 的优先级机制总结

    一.样式优先级: 多重样式(Multiple Styles):如果外部样式.内部样式和内联样式同时应用于同一个元素,就是使用多重样式的情况. 一般情况下,大家都认为优先级是:内联样式 > 内部样 ...

  6. wstring to wchar_t*

      If you want to convert from std::wstring to const WCHAR* (i.e. the returned pointer gives read-onl ...

  7. Could not find com.android.tools.build:gradle:3.0.0-alpha1 in circle ci

      Error:(1, 0) The android gradle plugin version 3.0.0-alpha1 is too old, please update to the lates ...

  8. BZOJ 1264 AHOI2006 基因匹配Match 动态规划+树状数组

    题目大意:给定n个数和两个长度为n*5的序列,每一个数恰好出现5次,求两个序列的LCS n<=20000.序列长度就是10W.朴素的O(n^2)一定会超时 所以我们考虑LCS的一些性质 LCS的 ...

  9. C# Lambda表达式 基础

    什么是Lambda 表达式? "Lambda表达式"实际上是一个方法,只不过该方法是一个匿名方法(就是没有名字的方法(函数),就是说只有在定义的时候能调用,在其他地方就不能调用了) ...

  10. 翻译记忆软件-塔多思TRADO经典教程_2

    Trados 中文简明教程Trados 中文简明教程1. 准备工作 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ...