在.NET中使用反射实现简易插件机制

在.NET中使用反射实现简易插件机制

  在.NET中使用反射实现简易插件机制

本篇是我学习反射的一个应用小场景而做的学习笔记java插件式开发,主要是一个小的总结,并对各个步骤的记录,以便将来回顾。

一、基础框架-敏捷基础版本

这里假定我们要开发一个记事本,选择 Form技术开发,界面如下图所示:

java插件式开发

该记事本只提供了一个供输入,以及保存到指定文件。其他功能均没有实现,假定我们先把这个版本做出来在.NET中使用反射实现简易插件机制,后续功能通过插件形式一步一步完成。

但是,为了能够使用插件,我们的主项目还得经过一些改造:

(1)加载时需要从插件目录中获取插件

    public FormMain()
    {
        InitializeComponent();
        // 加载插件
        LoadPlugins();
    }
    private void LoadPlugins()
    {
        // 1.加载plugins目录下的所有的dll文件
        string plugins = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "plugins");
        //   1.1 搜索plugins目录下的所有的dll文件 
        string[] dlls = Directory.GetFiles(plugins, "*.dll");
        // 2.循环将每个dll文件都加载起来
        foreach (string dllPath in dlls)
        {
            //  2.1 动态加载当前循环的dll文件
            Assembly assembly = Assembly.LoadFile(dllPath);
            //  2.2 获取当前dll中的所有的public类型
            Type[] types = assembly.GetExportedTypes();
            //  2.3 获取IEditor接口的Type
            Type typeIEditor = typeof(IEditor);
            for (int i = 0; i < types.Length; i++)
            {
                // 2.4 验证当前的类型即实现了IEditor接口并且该类型还可以被实例化
                if (typeIEditor.IsAssignableFrom(types[i]) && !types[i].IsAbstract)
                {
                    IEditor editor = (IEditor)Activator.CreateInstance(types[i]);
                    // 2.5 向菜单栏中动态添加一个菜单项
                    ToolStripItem toolItem = toolstripEditMenu.DropDownItems.Add(editor.PluginName);
                    // 2.6 为刚刚增加的菜单项注册一个单击事件
                    toolItem.Click += new EventHandler(toolItem_Click);
                    toolItem.Tag = editor;
                }
            }
        }
    }

(2)为插件设置通用的Click事件

    private void toolItem_Click(object sender, EventArgs e)
    {
        ToolStripItem item = sender as ToolStripItem;
        if (item != null)
        {
            if (item.Tag != null)
            {
                IEditor editor = item.Tag as IEditor;
                if (editor != null)
                {
                    // 运行该插件
                    editor.Execute(this.txtContent);
                }
            }
        }

这里约定所有插件都实现了接口,并且所有插件的功能都在方法中被实现。

二、约定接口-可扩展的基础

java插件式开发

java插件式开发

不难发现,如果我们直接使用反射调用dlljava插件式开发,即使我们找到了dll文件,也没法知道里面的函数叫什么名字java插件式开发,即使可以枚举出来,也没法智能的调用里面的函数,实现我们预期的功能扩展。于是我们犯难了,我们已经写好的程序哪能预料以后会调用哪些dll的哪些函数呢?

其实这个并不复杂,我们可以利用接口技术实现这样一种功能。所谓接口,就是一份协议在.NET中使用反射实现简易插件机制,当大家编写dll时都遵守这样一个协议,那么我们写的dll就可以方便的被exe调用。

对于这个小demo而言,我们设计一个接口如下:

    public interface IEditor
    {
        string PluginName
        {
            get;
        }
        void Execute(TextBox txtbox);
    }

其中,是插件的名称,用于菜单显示。方法则接收记事本的控件,用于实现具体的功能。

三、实现插件-可升级的功能

(1)插件1:将文本全部转为大写

新建一个类库项目,设计一个实现接口的类:

    public class ChangeFontStyle : IEditor
    {
        public string PluginName
        {
            get
            {
                return "转为大写";
            }
        }
        public void Execute(TextBox txtbox)
        {
            if (!string.IsNullOrEmpty(txtbox.Text))
            {
                txtbox.Text = txtbox.Text.ToUpper();
            }
            else
            {
                MessageBox.Show("请先输入文字!");
            }
        }

(2)插件2:将文本全部变为红色

新建一个类库项目,设计一个实现接口的类:

    public class ChangeFontColor : IEditor
    {
        public string PluginName
        {
            get
            {
                return "改变颜色";
            }
        }
        public void Execute(TextBox txtbox)
        {
            if (!string.IsNullOrEmpty(txtbox.Text))
            {
                txtbox.ForeColor = System.Drawing.Color.Red;
            }
            else
            {
                MessageBox.Show("请先输入文字!");
            }
        }
    }

四、拥抱变化-简单的测试

java插件式开发

(1)没有任何插件的记事本程序

插件目录下一个dll也木有:

java插件式开发

因此我们的记事本只有最基本的操作:

java插件式开发

(2)加入插件1(转换大写)的记事本程序

插件目录有一个dll:

java插件式开发

这时加入了转换大写的功能:

java插件式开发

(3)加入插件2(改变颜色)的记事本程序

插件目录有两个dll:

java插件式开发

这时加入了改变颜色的功能:

java插件式开发

由此可知,利用反射和接口,我们可以自定义插件实现不同的扩展功能,让我们的主软件项目更为强大!

公告:
1. 本站所有资源来源于用户上传和网络,如有侵权请联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系站长处理!
6. 本站不售卖代码,资源标价只是站长收集整理的辛苦费!如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
7. 站长QQ号码 2205675299

资源库 - 资源分享下载网 » 在.NET中使用反射实现简易插件机制

常见问题FAQ

关于资源售价和售后服务的说明?
本站所有资源的标价均为本站收集资源的辛苦费,不代表资源本身的价值。软件是高智慧高价值的商品,不可能是白菜价。本站资源标价只是赞助费用,收取的赞助费仅用来维持本站的日常运营!毕竟收集整理资料需要投入云计算资源和站长大量的精力。
代码有没有售后服务和技术支持?
由于代码的运行具有不可预见性,本站不保证代码完整可运行,不提供技术支持和售后服务。 本站原创代码都是站长自己开发的,可以有偿提供技术支持服务。 网站里标明【亲测】的代码都是站长亲测过的,其他的代码由于精力有限,没有一一测试,不能保证代码就一定能够使用,更没有技术支持服务,下载前请自行斟酌。
有没有搭建服务?
由于搭建服务比较费时费力,所以本站除了原创代码外均不提供搭建服务。本站分享代码纯属兴趣爱好,不以盈利为目的,请勿咨询有没有搭建服务,谢谢理解。
链接地址失效了怎么办?
请带上资源链接地址联系客服,工作时间内我们看到后将第一时间回复。
关于解压密码
本站资源一般都没有加密,如果发现需要解压密码的,那么就输入 hao.35dc.com 试试。

发表评论

资源库,由老程序员细心甄别、精心筛选,只为提供优质的源码资源

关于我们 联系我们