• c#插件式开发


    接着上一篇文章:http://blog.csdn.net/joyhen/article/details/22905481

    MEF:http://www.cnblogs.com/tcjiaan/tag/MEF/

    原文:http://blog.csdn.net/jam12315/archive/2008/08/18/2791534.aspx

    首先,新建一个类库,里面定义接口,这里定义两个方法,一个有返回值的,一个无返回值的。

    using System;  
    using System.Collections.Generic;  
    using System.Text;  
      
    namespace IMsg {  
        ///<summary>  
        /// 这是插件必须实现的接口,也是主程序与插件通信的唯一接口  
        /// 换句话说,主程序只认识插件里的这些方法  
        ///</summary>  
        publicinterface IMsgPlug {  void OnShowDlg();  string OnShowInfo();  
        }  
    }  
    将上面的类库生成IMsg.dll, 新建一个类库MYPlugin1,添加刚出的引用,分别新建两个类来实现IMsg中定义的接口。
    using System;  
    using System.Collections.Generic;  
    using System.Text;  
    using IMsg;  
    namespace MYPlugin1 {  
        publicclass myConsole: IMsgPlug {#region IMsgPlug成员publicvoid OnShowDlg() {  
                Console.WriteLine("控制台调用插件的OnShowDlg方法");  
            }  
            publicstring OnShowInfo() {  
                return "myConsole";  
            }#endregion  
        }  
    }  
      
    using System;  
    using System.Collections.Generic;  
    using System.Text;  
    using System.Windows.Forms;  
    using IMsg;  
    namespace MYPlugin1 {  
        publicclass MYDlg: Form,  
        IMsgPlug {#region IMsgPlug成员  
      
            publicvoid OnShowDlg() {  
                this.Text = "插件子窗体";  
                this.ShowDialog(); //调用Form的ShowDialog,显示窗体  
            }  
            publicstring OnShowInfo() {  
                return "MyDlg";  
            }#endregion  
        }  
    }  
    将上面的都生成dll, 生成目录可以设置为新建exe工程的bin目录plugins文件夹下。Plugins文件夹是新建的,专门存放插件的。 新建一个 WinForm项目来使用刚才的插件.


    using System;  
    using System.IO;  
    using System.Linq;  
    using System.Collections;  
    using System.Windows.Forms;  
    using System.Reflection;  
      
    namespace myConsole  
    {  
        public partial class Form1 : Form  
        {  
            /// <summary>  
            /// 应用程序的主入口点。  
            /// </summary>  
            [STAThread]  
            static void Main()  
            {  
                Application.EnableVisualStyles();  
                Application.SetCompatibleTextRenderingDefault(false);  
                Application.Run(new Form1());  
            }  
      
            public Form1()  
            {  
                InitializeComponent();  
            }  
      
            /// <summary>  
            /// 存放插件的集合  
            /// </summary>  
            private ArrayList plugins = new ArrayList();  
      
            //载入所有插件  
            private void btnLoadPlug_Click(object sender, EventArgs e)  
            {  
                string[] files = Directory.GetFiles(Application.StartupPath + "\plugins");  
                if (files != null)  
                    this.listBox1.Items.Clear();  
      
                foreach (var f in files)  
                {  
                    if (!f.ToUpper().EndsWith(".DLL"))  
                        continue;  
                    try  
                    {  
                        Assembly ab = Assembly.LoadFile(f);  
                        Type[] t = ab.GetTypes();  
                        foreach (var x in t)  
                        {  
                            if (x.GetInterface("IMsgPlug") != null)  
                            {  
                                plugins.Add(ab.CreateInstance(x.FullName));  
                                this.listBox1.Items.Add(x.FullName);  
                            }  
                        }  
                    }  
                    catch (Exception ex)  
                    {  
                        MessageBox.Show(ex.Message);  
                    }  
                }  
            }  
      
            //调用插件的方法  
            private void btnExecute_Click(object sender, EventArgs e)  
            {  
                if (this.listBox1.SelectedIndex == -1)  
                    return;  
      
                object selObj = this.plugins[this.listBox1.SelectedIndex];  
                Type t = selObj.GetType();  
                MethodInfo OnShowDlg = t.GetMethod("OnShowDlg");  
                MethodInfo OnShowInfo = t.GetMethod("OnShowInfo");  
      
                OnShowDlg.Invoke(selObj, null);  
                object returnValue = OnShowInfo.Invoke(selObj, null);  
                this.lblMsg.Text = returnValue.ToString();  
            }  
        }  
    }  

    运行结果:


    此方法用了反射,个人感觉效果不是很好。另外,注意dll对象的依赖,这种问题我在手写上面demo的时候发现了,首先要保证依赖文件的存在,再一个依赖文件的路径需要正确。另一点要说下,对反射后的验证可以做一些加强处理,listbox对象显示的名字可以通过给dll中对象添加特性标记,然后获取显示出来。下一节我们看看MEF的小例子。

    最后想说一下,这不是正在意义上的插件式开发,请参阅微软的MEF和MAF的设计

    出处:http://blog.csdn.net/joyhen/article/details/40072973

  • 相关阅读:
    apache 虚拟主机配置(根据不同的域名映射到不同网站)
    Tortoise SVN 使用笔记
    Apache 根据不同的端口 映射不同的站点
    jquery 获取当前元素的索引值
    修改ThinkPHP的验证码类
    NetBeans无法使用编码GBK安全地打开该文件
    在win2003下apache2.2无法加载php5apache2_4.dll
    我看软件工程
    PHP函数参数传递(相对于C++的值传递和引用传递)
    Notepad++ 使用正则表达式查找替换字符串
  • 原文地址:https://www.cnblogs.com/mq0036/p/7017494.html
Copyright © 2020-2023  润新知