zoukankan      html  css  js  c++  java
  • 也来学学插件式开发续-利用MEF

    前面一个博客:也来学学插件式开发中很多朋友留言说可以用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)

    如果我的文章对你有帮助,就点一下推荐吧.(*^__^*)
  • 相关阅读:
    Apache Pig的前世今生
    openssl之EVP系列之6---EVP_Encrypt系列函数编程架构及样例
    P3388 【模板】割点(割顶)
    让priority_queue支持小根堆的几种方法
    2017.11.7解题报告
    一个例子教你如何与出题人斗智斗勇
    debug
    树上倍增求LCA及例题
    素数的筛法
    Catalan卡特兰数入门
  • 原文地址:https://www.cnblogs.com/Alex80/p/6422005.html
Copyright © 2011-2022 走看看