之前在使用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的更多相关文章

  1. 手撸ORM浅谈ORM框架之基础篇

    好奇害死猫 一直觉得ORM框架好用.功能强大集众多优点于一身,当然ORM并非完美无缺,任何事物优缺点并存!我曾一度认为以为使用了ORM框架根本不需要关注Sql语句如何执行的,更不用关心优化的问题!!! ...

  2. 手撸ORM浅谈ORM框架之Add篇

    快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...

  3. 手撸ORM浅谈ORM框架之Update篇

    快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...

  4. 手撸ORM浅谈ORM框架之Delete篇

    快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...

  5. 手撸ORM浅谈ORM框架之Query篇

    快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...

  6. 【SSH学习笔记】浅谈SSH框架

    说在前面 本学期我们有一门课叫做Java EE,由陈老师所授,主要讲的就是Java EE 中的SSH框架. 由于陈老师授课风格以及自己的原因导致学了整整一学期不知道在讲什么,所以才有了自己重新学习总结 ...

  7. 浅谈angular框架

    最近新接触了一个js框架angular,这个框架有着诸多特性,最为核心的是:MVVM.模块化.自动化双向数据绑定.语义化标签.依赖注入,以上这些全部都是属于angular特性,虽然说它的功能十分的强大 ...

  8. 13.Object-C--浅谈Foundation框架常用的结构体

    ------- android培训.iOS培训.期待与您交流! ---------- 昨天学习了Foundation框架中常用的结构体,下面我简单的总结一下,如果错误麻烦请留言指正,谢谢! Found ...

  9. 2014-07-29 浅谈MVC框架中Razor与ASPX视图引擎

    今天是在吾索实习的第15天.随着准备工作的完善,我们小组将逐步开始手机端BBS的开发,而且我们将计划使用MVC框架进行该系统的开发.虽然我们对MVC框架并不是非常熟悉,或许这会降低我们开发该系统的效率 ...

随机推荐

  1. Nexus私服忘记用户名密码,Nexus私服如何找回用户名密码

    Maven搭建私服用Nexus很方便.但是如果忘记了管理员的密码,如何处理呢?Nexus私服如何找回用户名密码? 1. 找到nexus-XXXYYYY-bundle/sonatype-work/nex ...

  2. 2015 "BestCoder Cup" Champion

    这场比赛我没有参加,不过就算参加了也估计是被完虐.于是看着题解把大部分题目都搞了一遍. T1:Movie(hdu 5214) 题目大意: 给出N个区间,问能否选出3个互不相交的区间. N<=10 ...

  3. cocoapods 更新失败 bad response Not Found 404 (http://ruby.taobao.org/specs.4.8.gz)

    http://blog.csdn.net/dark_gmn/article/details/49274993 ERROR:  Could not find a valid gem 'cocoapods ...

  4. 《算法竞赛入门经典》5.41数学基础-Cantor的数表

    如下数列,第一项是1/1,第二项是1/2,第三项是2/1,第四项是3/1,第五项是2/2,…….输入n,输出第n项.1/1   1/2   1/3   1/4   1/52/1   2/2   2/3 ...

  5. 【转】NHibernate:no persister for 异常

    1.配置文件后缀名写错 mapping file 必须是.hbm.xml结尾 2.Web.config配置里面引用实体 <session-factory> <mapping asse ...

  6. 银光类似web visio的节点连线控件Essential Diagram免费下载地址

    Essential Diagram for Silverlight是一款功能强大的图解拓扑图控件,在XAML支持的情况下提供用户交互式地创建和编辑图解,支持数据绑定和多种布局,可以导出为多种文件格式等 ...

  7. SSH basics

    SSH, Secure SHell, was designed and created to provide the best security when accessing another comp ...

  8. 初试微信小程序

    2016年11月3日,微信小程序终于公测了,大家可以正式开发了.早在这之前,应公司要求,和同事就早早的试了一下微信小程序的开发,特此记录一下: 微信官方小程序文档:https://mp.weixin. ...

  9. Python 决策树的构造

    上一节我们学习knn,kNN的最大缺点就是无法给出数据的内在含义,而使用决策树处理分类问题,优势就在于数据形式非常容易理解. 决策树的算法有很多,有CART.ID3和C4.5等,其中ID3和C4.5都 ...

  10. unique函数的作用

    unique() 去重函数 unique()函数是一个去重函数,STL中unique的函数 unique的功能是去除相邻的重复元素(只保留一个),还有一个容易忽视的特性是它并不真正把重复的元素删除.他 ...