接着上一篇文章:http://blog.csdn.net/joyhen/article/details/22905481post
MEF:http://www.cnblogs.com/tcjiaan/tag/MEF/this
原文:http://blog.csdn.net/jam12315/archive/2008/08/18/2791534.aspxspa
首先,新建一個類庫,裏面定義接口,這裏定義兩個方法,一個有返回值的,一個無返回值的。.net
using System; using System.Collections.Generic; using System.Text; namespace IMsg { ///<summary> /// 這是插件必須實現的接口,也是主程序與插件通訊的惟一接口 /// 換句話說,主程序只認識插件裏的這些方法 ///</summary> publicinterface IMsgPlug { void OnShowDlg(); string OnShowInfo(); } }
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的設計3d
出處:http://blog.csdn.net/joyhen/article/details/40072973code