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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM