zoukankan      html  css  js  c++  java
  • ERP/MIS开发 开发LLBL Gen 插件(Plunin) Implementing a plugin

    以LLBL Gen作为ORM的首选开发工具,在经历几个项目之后,对它的认识又有了新的高度。一方面要对Query API熟练于心,这样写查询语句才会得心应手,另一方面,也在尝试从ORM的实现,源代码分析,扩展方面来了解这个ORM工具,以便在项目出现救急的问题时可以得心应手,临危不乱。

    这篇文章介绍LLBL Gen SDK中的内容,关于如何开发LLBL Gen插件的内容。这个Entity Visualizer插件是来源于ORM设计时,同时也想查看数据表的内容,于是产生了这个想法。功能好比.NET内置的Data Set Visualizer. 运行效果

    image

    从Table中选择一个表,下面的datagrid会显示这个表的所有数据。
    众所周知,开发插件最主要的工作是熟悉软件留下来的接口,以前自己设计插件框架来给别人开发插件,现在要反过来,用别人设计好的框架,来为之开发插件,所以,如果有开发过插件框架,可以少走一些弯路。
    LLBL Gen的插件放在安装目录的Plugins目录中,也可以通过修改LLBLGenPro.exe.config配置文件中的选项来修改
    <!-- Specification of the root folder where LLBLGen Pro will search for plugin assemblies -->
    <!-- This path is always relative to the application folder. -->
    <add key="pluginsRootFolder" value="Plugins"/>

    插件以.NET语言设计编码,多个插件可以放到一个程序集中,也可以分开为多个程序集。

    插件运行于LLBL Gen 容器中,有两种类型的用户界面接口,IPluginWindow用于独立的窗口,如下图,一个tab选项卡窗口,我们的插件dock在这个tab页面中,另一种是以控件的形式运行于指定的界面中,如下图

    image
    如果要设计这种界面类型的插件,请派生于IPluginConfigurationControl。

    启动Visual Studio,创建一个类库项目,到LLBL Gen的安装目录中,查找并添加对以下程序集的引用
    image

    添加一个新类型,派生于PluginBase。首先要重写Describe方法,这个方法用来显示我们插件的描述信息。
    public override PluginDescription Describe()
    {
               PluginDescription toReturn = base.Describe();

               toReturn.Build = _build;
               toReturn.Description = "Display the data of the specific mapping entity";
               toReturn.Id = new Guid("{1CCEEDD1-AD19-49c9-B711-BE2087D0F94A}");
               toReturn.Name = "Entity Visualizer Plug-in";
               toReturn.ShowProgressViewerDuringExecution = false;
               toReturn.TargetType = PluginTargetType.Entity;
               //toReturn.TypeOfPlugin = PluginType.SingleElementPlugin;
               toReturn.TypeOfPlugin = PluginType.DirectRun;
               toReturn.Vendor = "EPN Solution";
               toReturn.Version = _version;
               toReturn.SurpressProjectExplorerRedraw = false;
               return toReturn;
    }

    ShowProgressViewerDuringExecution 用于说明,在执行插件功能时,是否要显示进度条。
    来看一个TargetType 的类型,就是插件应用于哪种对象之上,比如项目,类型视图,实体,存储过程等。

    [Flags]
    public enum PluginTargetType
    {
            None = 0,
            Entity = 1,
            TypedList = 2,
            TypedView = 4,
            ActionSPCall = 8,
            RetrievalSPCall = 16,
            Project = 32,
            Object = 64,
    }
    我的Entity Visualizder插件是要显示表的数据,要应用的TargetType 那就是Entity.
    TypeOfPlugin是指插件类型,这个值会决定插件要应用的范围,来看它的值
    public enum PluginType
    {
          SingleElementPlugin = 0,    //一个元素
          MultiElementPlugin = 1,      //多个元素的插件
          SingleAndMultiElementPlugin = 2,   //单个或多个元素的插件
          DirectRun = 3,                //直接运行
          System = 4,                   //系统
    }
    Entity Visualizder插件是独立的可以直接运行的,所以它的TypeOfPlugin =DirectRun。
    如果 TypeOfPlugin =SingleElementPlugin 时,它的界面如下
    image

    运行插件的容器控件,会自动加载Target element:Entity:Customer,这是框架自动生成的。当TypeOfPlugin =MultiElementPlugin 时,它的界面如下 
    image

    出现了2个tab,第一个tab是选择要应用的对象,可以多选,第二个tab和上面是一样的界面。
    SurpressProjectExplorerRedraw 属性用来表示,当插件运行时,主界面是否要挂起,请对比下面的两张图image

    第二张图

    image

    区别看出来了,Project Explorer在SurpressProjectExplorerRedraw =true时,会像第二张图那样,把其中的内容藏起,以进行重绘,当它的值为false时,Project Explorer中的内容仍然会显示。

    为插件添加控件,前面说过,要在独立的tab窗体中运行插件,请添加新窗体并且派生于IPluginWindow
    public partial class EntityVisualizerControl : Form, IPluginWindow
    如果是在标准的容器界面中运行,请添加Windows控件,并派生于IPluginConfigurationControl
    public class AssignTypeConvertersControl : UserControl, IPluginConfigurationControl

    解释一下,标准的容器界面,如上图,有Target element标签,和两个按钮Run!/Cancel,这就是标准的容器界面。

    如果是控件,请添加如下的代码,以供标准容器界面加载些控件
    public override System.Windows.Forms.Control GetConfigurationControl()
    { _control = new AddCustomPropertiesConfigurationControl();
       return _control;
    }
    最后的一个步骤是,添加插件的运行代码,就是插件运行时,到底要做什么,重写Execute方法
    public override void Execute()
    {          
    EntityVisualizerControl _control = new EntityVisualizerControl(base.ProjectToTarget.ConnectionString, this);
         base.OpenDockedWindow(_control);
    }
    这里是打开独立的tab页面窗体,如果是控件,通常会用写样写
    public override void Execute()
            {
                _typeConversionsSelected = _control.SelectedTypeConversions;

                // 2 main tasks: entity, typed view
                base.ProgressTaskInit(2);

                base.ProgressTaskStart("Processing entities");
                base.ProgressSubtaskInit(base.Entities.Count);
                foreach(EntityDefinition entity  in base.Entities)
                {

                 }

    }
    _control是我们设计的控件,它接受用户输入后,当用户点击Run!按钮时,返回值给插件容器,执行Execute方法。
    这里会用到一些框架传回来的变量,比如base.Entities,是当前选择应用插件的实体元素,base.TypedViews视图。


    讲了这么多,都是讲如何与LLBL Gen的插件框架打交道,插件的功能还没有说明。插件在运行时,根据Project的连接字符串,连接到数据库中,应用下面的SQL语句,读取所有的表名
    select name from sysobjects where type='U'
    订阅cmbTables的SelectedIndexChanged事件,重新加载数据表grid中。

    如果对源代码感兴趣,请到epn.codeplex.com的Source Code中下载最新的源代码。

  • 相关阅读:
    webpack采坑十连跳
    白板编程
    Mysql加锁过程详解(1)-基本知识
    java单例模式几种实现方式
    mysql 幻读的详解、实例及解决办法
    MySQL执行计划extra中的using index 和 using where using index 的区别
    mysql INSERT ... ON DUPLICATE KEY UPDATE语句
    tk mybatis通用mapper,复杂and or条件查询
    tk.mybaits
    docker 笔记
  • 原文地址:https://www.cnblogs.com/JamesLi2015/p/2154190.html
Copyright © 2011-2022 走看看