1、主程式:
核心程式,把變動不大項目必須的部分寫入主程式。
以客戶管理為例:
在客戶管理中客戶基本檔案管理、客戶分類管理可以看做程式固定不變的部分也是程式初期必須實現的功能,作為主程式部分優先開發,客戶簡曆,客戶興趣愛好,客戶調查這些相對變化比較大,可以作為後期擴充開發,寫成外掛程式。
我們在這裡只說外掛程式開發實現部分,其它的不在詳述。
建立一個解決方案:外掛程式式開發客戶管理
在解決方案裡建立windows應用程式項目:CRM
到這裡先放下,進入外掛程式實現部分。
2、介面定義:
在解決方案裡建立一個類庫項目:CRM.IPlugin
在項目裡建立一個類:IVote.cs
代碼:
using System;namespace CRM.IPlugin{ public interface IVote { void Setup(); string GetPluginName(); }}
3:、外掛程式編寫:
在解決方案裡建立一個類庫項目:CRM.Plugins
添加引用:
.NET: System.Windows.Forms
項目: CRM.IPlugin
在項目裡建立一個表單:Vote.cs
表單代碼:
using System;using System.Collections.Generic;using System.ComponentModel;using System.Drawing;using System.Text;using System.Windows.Forms;namespace CRM.Plugins{ public partial class Vote : Form,CRM.IPlugin.IVote { public Vote() { InitializeComponent(); } private void Vote_Load(object sender, EventArgs e) { this.Text = "客戶投票調查"; } #region IVote 成員 public void Setup() { this.Show(); } public string GetPluginName() { return "客戶投票調查"; } #endregion }}
到此,外掛程式算是編寫完成。下面找到CRM專案檔夾在bin\debug目錄下建立目錄Plugins,回到vs方案總管中選擇CRM.Plugins項目,右鍵-》屬性-》產生-》輸出目錄設定為..\CRM\bin\Debug\Plugins\,最後再產生一下CRM.Plugins項目。
4、調用外掛程式:
回到項目CRM,開啟表單在表單上拖放一個ListBox控制項,切換到程式碼檢視輸入如下的代碼:
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;namespace CRM{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { this.LoadPlugins(); } //儲存外掛程式DLL檔案的路徑 private System.Collections.ArrayList PluginsDLL = new System.Collections.ArrayList(); /// <summary> /// 載入所有外掛程式 /// </summary> private void LoadPlugins() { try { //擷取Plugins目錄檔案 string[] PluginFiles = System.IO.Directory.GetFiles(Application.StartupPath + @"\Plugins"); foreach (string PluginFile in PluginFiles) { //dll檔案才是有效外掛程式程式集 if (PluginFile.ToUpper().EndsWith(".DLL")) { //通過反射載入dll程式集 System.Reflection.Assembly Ab = System.Reflection.Assembly.LoadFrom(PluginFile); //擷取載入的dll程式集裡面的類名稱 Type[] Types = Ab.GetTypes(); foreach (Type T in Types) { //檢查類是否實現了定義的IVote介面 if (T.GetInterface("IVote") != null) { listBox1.Items.Add(T.FullName); PluginsDLL.Add(PluginFile); } } } } } catch (Exception ex) { MessageBox.Show(ex.Message); } } /// <summary> /// 調用外掛程式方法 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void listBox1_Click(object sender, EventArgs e) { try { if (listBox1.SelectedIndex == -1) { return; } string PluginDLLFile = PluginsDLL[listBox1.SelectedIndex].ToString(); //載入外掛程式DLL程式集 System.Reflection.Assembly Ab = System.Reflection.Assembly.LoadFrom(PluginDLLFile); //建立外掛程式中名稱為listBox1中選中項名稱的類的執行個體 object Plugin = Ab.CreateInstance(listBox1.SelectedItem.ToString()); Type T = Plugin.GetType(); //擷取類中的方法GetPluginName System.Reflection.MethodInfo PluginMethodReturnValue = T.GetMethod("GetPluginName"); //執行有傳回值的方法 object returnValue = PluginMethodReturnValue.Invoke(Plugin, null); MessageBox.Show("您調用的外掛程式是:"+returnValue.ToString()); //擷取類中的方法Setup System.Reflection.MethodInfo PluginMethod = T.GetMethod("Setup"); //執行無傳回值的方法 PluginMethod.Invoke(Plugin, null); } catch (Exception ex) { MessageBox.Show(ex.Message); } } }}
5、總結:
外掛程式式編程是犧牲了程式的一部分執行效率來換得開發效率,我也只是初步理解。
對於這個樣本程式來說,我覺得最大的缺陷有以下幾點:
1、調用外掛程式方法的時候每次都要載入外掛程式DLL檔案和建立相應的執行個體,這裡還有很大的效能改進空間,應該可以用緩衝來儲存建立的執行個體,但是由於對winform下的緩衝我還沒有掌握,暫時沒有解決。
2、每次調用都會開啟一個視窗,我想到一個解決辦法就是在外掛程式表單調用方法Setup裡檢測表單是否在applicaton.openForm裡面,在的話就把建立的對象釋放掉,不在則顯示,覺得不是那麼好,希望大家給出更好的辦法。
代碼如下,修改CRM.Plugins裡面的vote表單的Setup方法:
public void Setup() { System.Windows.Forms.FormCollection FormColl = Application.OpenForms; if (FormColl[this.Name] != null) { (FormColl[this.Name] as Form).WindowState = FormWindowState.Normal; (FormColl[this.Name] as Form).Focus(); this.Dispose(); } else { this.Show(); } }