MongoDB管理工具的插件系统

MongoDB管理工具  MongoCola的开发已经进入第三个年头了。

官方对于C#驱动的投入不够导致了很多东西都必须自己实现,但是不管怎么样,工具现在已经很强大了。

最近准备着手插件系统的开发,简单的插件系统,其实代码量非常的少。

1.插件基类

插件系统需要一个插件基类的支持,这个基类,规定了一个插件所包含的固有字段,例如插件名称,插件说明,插件作者等等。

同时,还定义了主方法的名称,毕竟插件系统肯定要使用反射来完成,所以很多东西必须要统一起来。

 1 using System;
 2 
 3 namespace MagicMongoDBTool.Common
 4 {
 5     public abstract class PlugBase
 6     {
 7         /// <summary>
 8         /// 路径阶层[考虑到以后可能阶层会变换]
 9         /// </summary>
10         public enum PathLv : int
11         {
12             /// <summary>
13             /// 连接/服务器
14             /// </summary>
15             ConnectionLV = 0,
16             /// <summary>
17             /// 具体的实例
18             /// </summary>
19             InstanceLV = 1,
20             /// <summary>
21             /// 数据库
22             /// </summary>
23             DatabaseLV = 2,
24             /// <summary>
25             /// 数据集
26             /// </summary>
27             CollectionLV = 3,
28             /// <summary>
29             /// 数据文档
30             /// </summary>
31             DocumentLV = 4,
32             /// <summary>
33             /// 杂项
34             /// </summary>
35             Misc = 9
36         }
37         /// <summary>
38         /// 插件菜单表示名称
39         /// </summary>
40         public string PlugName = String.Empty;
41         /// <summary>
42         /// 插件功能简述
43         /// </summary>
44         public string PlugFunction = String.Empty;
45         /// <summary>
46         /// 处理对象
47         /// </summary>
48         public dynamic PlugObj;
49         /// <summary>
50         /// 对象层次
51         /// </summary>
52         public PathLv RunLv = PathLv.ConnectionLV;
53         /// <summary>
54         /// 运行
55         /// </summary>
56         /// <returns></returns>
57         public abstract int Run(); 
58     }
59 }

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

原文地址:https://www.cnblogs.com/TextEditor/p/3518744.html