• 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

  • 相关阅读:
    angular2怎么使用第三方的库(jquery等)
    线性代数:方程组的几何解释
    2016新的计划
    ES+Hbase对接方案概述
    sparkR操作HDFS上面的CSV文件
    spark1.6配置sparksql 的元数据存储到postgresql中
    spark读写Sequoiadb
    Spring Boot与Docker部署
    Docker中使用Tomcat并部署war工程
    CentOS7安装使用Docker
  • 原文地址:https://www.cnblogs.com/TextEditor/p/3518744.html
Copyright © 2020-2023  润新知