MongoDB管理工具 MongoCola的開發已經進入第三個年頭了。
官方對於C#驅動的投入不夠導致了很多東西都必須自己實現,但是不管怎麼樣,工具現在已經很強 大了。
最近准備著手插件系統的開發,簡單的插件系統,其實代碼量非常的少。
1.插件基類
插件系統需要一個插件基類的支持,這個基類,規定了一個插件所包含的固有字段,例如插件名稱 ,插件說明,插件作者等等。
同時,還定義了主方法的名稱,畢竟插件系統肯定要使用反射來完成,所以很多東西必須要統一起 來。
using System; namespace MagicMongoDBTool.Common { public abstract class PlugBase { /// <summary> /// 路徑階層[考慮到以後可能階層會變換] /// </summary> public enum PathLv : int { /// <summary> /// 連接/服務器 /// </summary> ConnectionLV = 0, /// <summary> /// 具體的實例 /// </summary> InstanceLV = 1, /// <summary> /// 數據庫 /// </summary> DatabaseLV = 2, /// <summary> /// 數據集 /// </summary> CollectionLV = 3, /// <summary> /// 數據文檔 /// </summary> DocumentLV = 4, /// <summary> /// 雜項 /// </summary> Misc = 9 } /// <summary> /// 插件菜單表示名稱 /// </summary> public string PlugName = String.Empty; /// <summary> /// 插件功能簡述 /// </summary> public string PlugFunction = String.Empty; /// <summary> /// 處理對象 /// </summary> public dynamic PlugObj; /// <summary> /// 對象層次 /// </summary> public PathLv RunLv = PathLv.ConnectionLV; /// <summary> /// 運行 /// </summary> /// <returns></returns> public abstract int Run(); } }
Run是個抽象方法,既然是抽象方法,繼承這個類的插件都必須實現這個方法。Run也是以後工具調 用插件功能的入口函數。
這個基類,可以以源代碼的形式添加到插件的工程裡面,當然,也可以做成一個DLL,讓插件的工程 引用。我現在講它做成了DLL。
2.工具如何發現插件
做法也很簡單,所有的插件的DLL統一放在指定目錄中,然後使用強大的反射,獲取插件的基本情報 ,放在字典裡面
using MagicMongoDBTool.Common; using System; using System.Collections.Generic; using System.Reflection; using System.Windows.Forms; namespace MagicMongoDBTool.Module { public class PlugIn { public static Dictionary<String, PlugBase> PlugInList = new Dictionary<string, PlugBase>(); /// <summary> /// 加載到菜單項目 /// </summary> public static void LoadPlugIn() { ///注意 ///必須將Common.DLL放在Bin下面! foreach (var mFile in System.IO.Directory.GetFiles(Application.StartupPath + @"\PlugIn\","*.dll")) { try { Assembly mAssem = Assembly.LoadFile(mFile); String FileName = mFile.Replace(Application.StartupPath + @"\PlugIn\", String.Empty); if (FileName == "MagicMongoDBTool.Common.dll") continue; String TypeName = FileName.Substring(0, FileName.Length - 4); Type mType = mAssem.GetType(TypeName + "." + TypeName); ConstructorInfo ConstructorInfo = mType.GetConstructor(new System.Type[] {}); PlugBase mPlug = (PlugBase)ConstructorInfo.Invoke(new object[] { }); PlugInList.Add(TypeName, mPlug); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); } } } } }
這裡需要注意一個問題,由於插件使用了插件基類PlugBase,PlugBase是放在一個獨立的DLL中的, 所以,請將這個DLL放在可執行文件的同一目錄下面。
理由是,反射執行的時候,需要訪問PlugBase基類的構造。(可能是這樣吧)
3.將插件展示在菜單裡面
PlugIn.LoadPlugIn(); foreach (var plugin in PlugIn.PlugInList) { ToolStripItem menu = new ToolStripMenuItem(plugin.Value.PlugName); menu.ToolTipText = plugin.Value.PlugFunction; menu.Tag = plugin.Key; menu.Click += new EventHandler( (x, y) => { RunPlugIn(plugin.Key); } ); this.plugInToolStripMenuItem.DropDownItems.Add(menu); }
就是一個很簡單的動態創建菜單
查看本欄目
4.運行插件
/// <summary> /// 運行插件 /// </summary> /// <param name="PlugInKeyCode"></param> private void RunPlugIn(string PlugInKeyCode) { System.Reflection.Assembly mAssem = Assembly.LoadFile(Application.StartupPath + @"\PlugIn\" + PlugInKeyCode + ".dll"); String TypeName = PlugInKeyCode; Type mType = mAssem.GetType(TypeName + "." + TypeName); ConstructorInfo ConstructorInfo = mType.GetConstructor(new System.Type[] { }); PlugBase mPlug = (PlugBase)ConstructorInfo.Invoke(new object[] { }); switch (PlugIn.PlugInList[PlugInKeyCode].RunLv) { case MagicMongoDBTool.Common.PlugBase.PathLv.ConnectionLV: mPlug.PlugObj = SystemManager.GetCurrentServer(); break; case MagicMongoDBTool.Common.PlugBase.PathLv.InstanceLV: mPlug.PlugObj = SystemManager.GetCurrentServer(); break; case MagicMongoDBTool.Common.PlugBase.PathLv.DatabaseLV: mPlug.PlugObj = SystemManager.GetCurrentDataBase(); break; case MagicMongoDBTool.Common.PlugBase.PathLv.CollectionLV: mPlug.PlugObj = SystemManager.GetCurrentCollection(); break; case MagicMongoDBTool.Common.PlugBase.PathLv.DocumentLV: break; default: break; } mPlug.Run(); }
采用反射運行插件,沒有什麼技術含量。
5.簡單的做了一個Sample,學過MongoDB的,自然看得懂了
using MagicMongoDBTool.Common; using MongoDB.Driver; using System.Windows.Forms; namespace ExportToExcel { public class ExportToExcel:PlugBase { /// <summary> /// 內部變量 /// </summary> MongoCollection ProcessCollection; /// <summary> /// 初始化設定 /// </summary> public ExportToExcel() { base.RunLv = PathLv.CollectionLV; base.PlugName = "導出到Excel工具"; base.PlugFunction = "將數據集導出到Excel"; } /// <summary> /// 運行 /// </summary> /// <returns></returns> public override int Run() { ProcessCollection = base.PlugObj; MessageBox.Show(ProcessCollection.Name); return 0; } } }
園子裡面使用MongoDB的朋友不是很多,我想找個朋友一起來繼續開發這個工具。或者找人幫我開發 一些插件。
中國的開源項目,期初很熱鬧,但是過一段時間,就冷清了。我想找的開發伙伴,希望能耐得住寂 寞,能夠長期保持開發熱情。
人不需要太多,1個2個就可以了。
工具官方網址
http://www.mywechatapp.com/
GitHub
https://github.com/magicdict/MagicMongoDBTool