• 也来学学插件式开发续利用MEF


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

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

    MEF如何工作?

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

    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)

    如果我的文章对你有帮助,就点一下推荐吧.(*^__^*)
  • 相关阅读:
    sublime Text3插件无法安装解决方法(提示There are no packages available installation)
    扫码消费数量栏点击可编辑,失去焦点还原样式
    浏览器内核
    js全选checkbox框
    word-wrap: break-word;与word-break: break-all;文本自动换行
    含加减的输入框
    linux ,mac连接, git pull error, chmod修改文件的权限/chown修改文件和目录的所有者
    vue修改对象的属性值后页面不重新渲染
    jsp 判断时间大小
    利用js实现 禁用浏览器后退| 去除上一个历史记录链接
  • 原文地址:https://www.cnblogs.com/Gyoung/p/2934037.html
Copyright © 2020-2023  润新知