浅谈可扩展性框架:MEF
之前在使用Prism框架时接触到了可扩展性框架MEF(Managed Extensibility Framework),体验到MEF带来的极大的便利性与可扩展性。
此篇将编写一个可组合的应用程序,帮助大家快速熟悉MEF并将其应用于实际项目中。
有关MEF中的名词含义及功能实现,请大家移步:火车票
介绍下将要编写的Demo程序(下图),使用winform开发。
- 通过组合操作,程序动态加载可用部件进行组合操作。
- 通过解体操作,程序卸载所加载的所有部件。

新建项目后需引用程序集:
System.ComponentModel.Composition
主程序的核心代码如下:
public partial class Form1 : Form, IPartImportsSatisfiedNotification
{
[ImportMany(AllowRecomposition = true)]
private IEnumerable<Lazy<IPlugin, IPluginMetadata>> plugins; private AggregateCatalog catalog;
private CompositionContainer container;
public Form1()
{
InitializeComponent();
if (catalog == null)
catalog = new AggregateCatalog();
this.container = new CompositionContainer(catalog);
this.container.ComposeParts(this);
} #region Implementation of IPartImportsSatisfiedNotification
public void OnImportsSatisfied()
{
flowLayoutPanel1.Controls.Clear();
if (plugins != null && plugins.Count() != )
{
plugins.ToList().ForEach((a) =>
{
Button btn = new Button();
btn.Cursor = System.Windows.Forms.Cursors.Hand;
btn.Width = ;
btn.Height = ;
btn.Text = a.Metadata.ThePluginName;
btn.Click += (d, b) => { a.Value.Run(); };
flowLayoutPanel1.Controls.Add(btn);
});
}
}
#endregion public void CompositionAction()
{
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
}
......
}
1. IPartImportsSatisfiedNotification接口 : 在组件导入完成后,调用该接口中的方法(OnImportsSatisfied)。
2. MEF中最常用目录有三种:程序集目录(AssemblyCatalog),文件目录(DirectoryCatalog),聚合目录(AggregateCatalog)
程序集目录(AssemblyCatalog): 顾名思义可以向目录中添加程序集已存在类型中寻找可用于导入的部件。
var catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly());
文件夹目录(DirectoryCatalog):从文件夹中寻找可用于导入的部件
var catalog = new DirectoryCatalog("Extensions");
聚合目录(AggregateCatalog):可以向聚合目录包含上述两种方式
var catalog = new AggregateCatalog(
new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()),
new DirectoryCatalog("Extensions"));
3. CompositionContainer : 组合容器,管理部件的组合并提供了一系列用于创建部件实例扩展方法等,详细资料
4. 目录与容器的一般使用方法:
var catalog = new AggregateCatalog();
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
5. 导入:ImportAttribute 与 ImportManyAttribute
用于以下三种用途:字段,属性,方法
[import]
private IData _data; [import]
public IData Data{set;get;} [import]
public Action ClickAction;
ImportManyAttribute : 通过组合容器将所有符合契约的导出进行填充 (真别扭,说白了就是导入多个)
[ImportMany]
private IEnumerable<IPlugin> plugins;
AllowRecomposition : 是否允许重组
AllowRecomposition = true : 比如在程序运行的过程中,动态向聚合目录中添加可导出的部件,可以引发重组操作
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
需要注意的是:DirectoryCatalog 不会引发重组操作,可通过Refresh方法指定重组的策略。
6. System.Lazy<T> : MEF提供延迟导入。
下面来看一下,插件式如何实现的:
[ExportPluginAttribute(typeof(IPlugin), ThePluginName = "TheFristPlugin")]
public class TheFristPlugin : IPlugin
{
public TheFristPlugin()
{
this.TheName = "TheFristPlugin";
}
#region Implementation of IPlugin public string TheName { get; set; } public void Run()
{
MessageBox.Show("TheFristPlugin");
} #endregion
}
1. 简单说一下:导入与导出之前的关系
一个基于MEF开发的可扩展的程序,在容器中必然有很多的导出(Export),而这些Export又是怎么样找到自己的归宿呢。
Export 与 Import 依靠一种契约,来确定对方是否是自己的兄弟,说白了就是接口,比如上述程序所定义的IPlugin接口
public interface IPlugin
{
void Run();
}
使用 ExportAttribute 特性导出:
[Export("count")]
public int count{ get{return ;} }
[Export(typeof(Action))]
public void SendMsg(){return;}
[Export]
public class Person{}
有一个需求,主程序要求插件必须要指定插件名称:
1. 在IPlugin接口中定义:Name字段
2. 使用元数据
3. 使用自定义导出特性(与第二种方案类似)
如何使用元数据?
1.定义元数据视图,此处视图使用接口类型
public interface IPluginMetadata
{
string ThePluginName { get; }
}
2. 导出部件时,使用ExportMetaData特性
[ExportMetadata("ThePluginName", "TheFivePlugin")]
[Export(typeof(mef.test.wform.Interface.IPlugin))]
public class TheFivePlugin : mef.test.wform.Interface.IPlugin
{
public void Run()
{
MessageBox.Show("TheFivePlugin");
}
}
3. 导入元数据
[ImportMany(AllowRecomposition = true)]
private IEnumerable<Lazy<IPlugin, IPluginMetadata>> plugins;
4. 访问元数据
Lazy<T,TMetadata>.Value.Metadata
结束
到此为止,MEF 基本内容已讲解结束,如果有遗漏也请博友留言指出。
文章中很多都是白话,非官方语言,怎么理解的就怎么写,如果有不妥之处,还望各位博友指出。
新年快乐
浅谈可扩展性框架:MEF的更多相关文章
- 手撸ORM浅谈ORM框架之基础篇
好奇害死猫 一直觉得ORM框架好用.功能强大集众多优点于一身,当然ORM并非完美无缺,任何事物优缺点并存!我曾一度认为以为使用了ORM框架根本不需要关注Sql语句如何执行的,更不用关心优化的问题!!! ...
- 手撸ORM浅谈ORM框架之Add篇
快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...
- 手撸ORM浅谈ORM框架之Update篇
快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...
- 手撸ORM浅谈ORM框架之Delete篇
快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...
- 手撸ORM浅谈ORM框架之Query篇
快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...
- 【SSH学习笔记】浅谈SSH框架
说在前面 本学期我们有一门课叫做Java EE,由陈老师所授,主要讲的就是Java EE 中的SSH框架. 由于陈老师授课风格以及自己的原因导致学了整整一学期不知道在讲什么,所以才有了自己重新学习总结 ...
- 浅谈angular框架
最近新接触了一个js框架angular,这个框架有着诸多特性,最为核心的是:MVVM.模块化.自动化双向数据绑定.语义化标签.依赖注入,以上这些全部都是属于angular特性,虽然说它的功能十分的强大 ...
- 13.Object-C--浅谈Foundation框架常用的结构体
------- android培训.iOS培训.期待与您交流! ---------- 昨天学习了Foundation框架中常用的结构体,下面我简单的总结一下,如果错误麻烦请留言指正,谢谢! Found ...
- 2014-07-29 浅谈MVC框架中Razor与ASPX视图引擎
今天是在吾索实习的第15天.随着准备工作的完善,我们小组将逐步开始手机端BBS的开发,而且我们将计划使用MVC框架进行该系统的开发.虽然我们对MVC框架并不是非常熟悉,或许这会降低我们开发该系统的效率 ...
随机推荐
- linux 基本命令操作
1.ls 命令 ls -a 列出所有文件,包括隐藏文件 ls -l 列出文件详细信息 ls -r 列出所有文件包括文件夹 查询具体文件可以在命令后面加 |grep 要匹配的字符串,方便我们查找, ...
- macbook上实现MacOS+Windows8+Ubuntu三系统
至于为什么要装win和linux就不说了,本文只解释安装过程. GPT vs MBR MacOS下装另外两个系统的一个基本问题是:硬盘使用GPT分区,它和常见的MBR分区是两个硬盘分区方式. 它们的主 ...
- at
1.这个命令对于自己建立的虚拟机很有帮助,比如你想过半个小时关机: [root@oc3408554812 ~]# at now + 30 minutesat> cd /tmp -h nowat& ...
- Android - ViewPager+Fragment初始化问题
Android应用开发中,经常会用到ViewPager + Fragment,虽然效果不错,但随之而来的还有一些问题,下面就说说其中的初始化问题. ViewPager初始化时会预加载前后的2个页面,即 ...
- 关于MySQL中的left join、on、where的一点深入
原文地址:http://www.oschina.net/question/89964_65912?sort=default&p=3#answers 即使你认为自己已对 MySQL 的 LEFT ...
- 关于ASP.NET页面打印技术的总结【转】
B/S结构导致了Web应用程序中打印的特殊性. • 程序运行在浏览器中,打印机在本地,而文件确可能在服务器上,导致了打印控制不是很灵活. • 格式如何控制和定制等,是我们开发中可能会面对的问题. 打印 ...
- windows核心编程---第七章 用户模式下的线程同步
用户模式下的线程同步 系统中的线程必须访问系统资源,如堆.串口.文件.窗口以及其他资源.如果一个线程独占了对某个资源的访问,其他线程就无法完成工作.我们也必须限制线程在任何时刻都能访问任何资源.比如在 ...
- windows下安装RabbitMq-Service
一.RaibbitMQ服务器配置 1. 准备工作.如果之前安装过RabbitMQ软件,若想重新安装,必须先把之前的RabbitMQ相关软件卸载. 2. 安装ERLANG语言包.首先到http://ww ...
- XML Schema的基本语法(转)
XML Schema的基本语法(转) XSDL(XML Schema定义语言)由元素.属性.命名空间和XML文档种的其他节点构成的. 一.XSD中的元素 XSD文档至少要包含:schema根元素和XM ...
- struts2 ajax的一种实现方式
/** * ajax请求,通过省份id获取学习中心 */ public void getSitesByPid() { HttpServletResponse response = ServletAct ...