首页 C_创建插件业务平台

C_创建插件业务平台

举报
开通vip

C_创建插件业务平台C_创建插件业务平台 C# 创建插件业务平台 任钢 摘 要 , 在 中采用反射机制 , 通过动态参数输入和动态数据结果输出 , 实现业务的外部 C# 维护。 以此为基础创建了一个插件平台 , 说明插件平 台实现的技术基础 、 实现思路和实现 的 步骤, 并给出了插件平台的 C# 程序源代码 。 关键词 , , 放射机制 , 动态参 数 , 插件平 台C# 了 解如下的类似信息 , 如构造函数的名 称 、 参 CoustructorInfo 1 引言 数 、 访 问 修 饰 符 (如 public 或 ...

C_创建插件业务平台
C_创建插件业务平台 C# 创建插件业务平台 任钢 摘 要 , 在 中采用反射机制 , 通过动态参数输入和动态数据结果输出 , 实现业务的外部 C# 维护。 以此为基础创建了一个插件平台 , 说明插件平 台实现的技术基础 、 实现思路和实现 的 步骤, 并给出了插件平台的 C# 程序源代码 。 关键词 , , 放射机制 , 动态参 数 , 插件平 台C# 了 解如下的类似信息 , 如构造函数的名 称 、 参 CoustructorInfo 1 引言 数 、 访 问 修 饰 符 (如 public 或 private) 和实现详细信 息 (如 在信息系统开发 , 用 户 业务功能变化预先不可知 , 故 要 提 ab- stract或 virtua1) 等 , 4, , 使 用 MethodInfo来了解如下的 高系统后期的业务扩展 。 一 般情况下用户需求发生变化 , 要 重 类似 信 息 , 如 方 法 的 名 称 、 返 回 类 型 、 参 数 、 访 问 修 饰 符 (如 新 编 写 代 码 , 编 译 , 生 产 部 署 包 , 然后再更新用户程 序 , 这 pub- lic 或 private) 和实现详细信 息 (如 abstract或 virtua1) 等 , 样 的过程比较繁琐 。 ,5,使 用 FieldInfo来了解如下的类似信 息 , 如 字 段 的 名 称 、 访 本文讨论生成后的应用 系统与外部编译的业务库实现动态 问 修 饰 符 (如 public 或 private) 和实现详细信息 ( 如 static) 绑 定 , 应用程序在运行过 程 中动态绑定要实现的外部业务 。 当 等 , 并 获取或设置字段值 , 6 , , 使 用 EventInfo来了解如下的 业 务 发 生 变 化 , 也 只 是 替 换 这些外部的动态库 , 不 用 重 新 对 应 类似信 息 , 如 事 件 的 名 称 、 事 件 处理程序数据类型 、 自 定 义 属 用程序进行修改和编译 ,实 现 了 耦 合 绑 定 。 同 时 ,业 务 实 例 对 性 、 声 明类型和反射类型等 , 并 添 加 或 移除事件处理程序 , 象可以在程序运行时实现实 例 化 , 达到了封装效 果 , 并 且 降 低 来了解如下的类 似 信 息 ,、 数 据 用 如 属 性 的 名 称 ,7, 使 PropertyInfo 了调用代码和具体实现类代码的耦合 , 增 强 灵活性和可复用 类 型 、 声 明 类 型 、 反 射 类 型和只读或可写状态等 , 并 获 取 或 设 性 , 增加了软件的可 维护性 。 置 属 性 值 , 8, , 使 用 ParameterInfo来 了 解 如 下 的 类 似 信 C# 提供的反射机制 , 再结合自适应数据参数的传 递 , 通 息 ,如 参 数 的 名 称 、 数 据 类 型 、 参数是输入参数还是输出参 过 这 个 技 术 , 可以将应用 框 架中的扩展点以插件式程序集的方 数 , 以 及参数在方法签名中的位置等 。 式 来 动 态 加 载 、 构 建 , 从而实现可动态扩展的应用程 序 。 3 设计思路 2 反射机制 插件是一种遵循一定 规范的应用程序接口编写出来的程序 模 块 。 当应用程序已经部 署 , 业务却发生了变 化 , 这 样 可 以 通 反 射 是 .NET 中 重 要 机 制 , 通 过 反 射 , 可以在运行 时获得 . 过读取插件配置信息 , 载入新的应用构 件 , 实现变化的业 务 。 NET 中 每 一 个 类 型 (包 括 类 、 结 构 、 委 托 、 接 口 和 枚 举 等 ) 的 对于应用系统的框架 而 言 , 扩展点是框架中预先定义的 一 成 员 , 包 括 方 法 、 属 性 、事 件 , 以及构造函数 等 , 还 可 以 获 得 每个成员的名称 、 限定符和参数 等 。 .NET 的 应 用 程 序 结 构 分 些 “ 点 ” 。 在框架复用中应用构件的组装需要基于扩展点 为 应 用 程 序 域 、程 序 集 、 模 块 、 类型和成员几个层 次 , 公 共 语 进 行 。 构造性和演化性是 软 件的两个本质特征 , 作为一类重要 言运行库加载器管理应用程 序 域 的 可复用软件制品 , 这种管理包括将每个程序 集 。 而 基 于 扩展点可以组装不同的应用构件以加载到相应的应用程序域以 及控制每个程序集中类型层次结构 适 应领域的变化性 , 则体现了框架对于软件演化特征的支 持 。 的 内 存 布 局 。 程序集包含模 块 , 而模块包含类 型 , 类 型 又 包 含 本文涉及到几个概念 , 插 件 配 置 定 义 、 接 口 定 义 、 方 法 定 成 员 , 反射则提供了封装 程 序 集 、 模块和类型的对 象 。 可 以 使 义 、 调用参数定义和返 回 参 数 定 义 。 在本插件平台 中 , 配 置 文 用反射动态地创建类型的实例 , 将类型绑定到现有对象或从 现 件描述插件配置定义 , 接 口 定 义 , 方 法 定 义 。 对于调用参数 定 有对象中获取类型 , 然后调用类型的方法 或 访问其字段和属 义和返回参数定义则采用 通用对象和动态对象组来实现传入和 性 。 返 回 参 数 。 反射通常具有以下用途 , 1 , , 使 用 Assembly定 义 和 加 载 插件平台的实现过程如图 1 所 示 。 当平台运行初始化 时 , 程 序 集 , 加载在程序集清 单 中 列 出 的 模 块 , 以及从此程序集 中 通 过 读 取 XML 配 置 信 息 , 装 载 DLL, 通 过 C# 的反射机制分析 查 找 类 型并创建该类型的实例 , 2 , , 使 用 Module了 解 如 下 的 DLL 里的全部实现类和方法 。 外部构件可以在平台容器中被 实 类 似 信 息 , 如模块的程序集以及模 块 中 的 类 等 , 3, , 使 用 例 化 , 并执行插件点的方 法 。 实现的算法不再是编码硬绑 定 。 在 实 现 将 树状结构的数据转换为二维 XML MethodObject 哈 希 表 , MethodObject 哈 希 表 是 一 个 key/value的 键 值 对 , 其 中 key 通常可用来快速查找 , value 用于存储对应 于 key 的 值 。 整 个 过 程 图图 1 PlugPlatform MethodObject类数据结构如 下 , 这 样 , 应用程序在运行过程中动态绑定 要 实 现 的 外 部 业 public class MethodObject { 务 , 当业务发生变 化 , 也 只 是替换这些外部的动态库 , 不 用 重 private ClassObject classobject = null; 新对应用程序进行修改和编译 , 实现了耦合绑 定 。 private InterfaceObject interfaceobject = null; private DllFileObject dllfileobject = null; 4 具体实现 private string name = string.Empty; PlugPlatform平 台 包 括 四 个 部 分 , ,, 配置文件的获取和 1 private string simplename = string.Empty; 解 析 , , , 通用参数和动 态 参 数 组 处 理 , , , 插 件 平 台 装 载23 private string implementname = string.Empty; DLL 并执行外部方法 , 4 , , 异 常 处 理 。 public string MethodName {get { return this.name; } set { this.name = value; } } 4.1 配置文件的获取和解析 public string SimpleName { get { return this.simplename; } 配 置 文 件 以 XML Schema为 基 础 , 分 为 两 种 类 型 , 一 种 是 set { this.simplename = value; } } 类 配 置 文 件 , 主要描述关于外 部 DLL 中的类以及方法的内容 , public string ImplementName {get { return this.implement- 中主要描述关于外部 第二种配置文件是接口配置文件 , DLL name; }set { this.implementname = value; }} 的接口以及方法的内容 。 public ClassObject ClassObject {get { return this.classob - ject; }set { this.classobject = value; }} 类 配 置 文 件 的 如 图 所 示 。XSD 2 public InterfaceObject InterfaceObject {get {return this.in- terfaceobject; }set {this.interfaceobject = value; }} public DllFileObject DLLFileObject { get { return this.dll- 图 类 配 置 文 件 的 图2 schema fileobject; } set { this.dllfileobject = value; }} } 按 照 此 XSD形 成 的 配 置 XML 如 图 3 所 示 。 哈 希 表 中 为 保 证 内 容的唯一性而采用方 MethodObject key 同理可以接口配 置 文 件 的 XSD内 容 ,如 图 4, 和 树XML 。 这样形成的主键可以进行快速查找 法 的 全 名 。 可 以 , value ,如 图 5, 。用 来 存 储 对 象 。 同 时 对 象 与 MethodObject MethodObject Class Object对 象 , InterfaceObject 对 象 和 DLLFile对 象 都 是 多 对 一 的 关 系 。 所 以 , 一 旦 获 得 了 MethodObject对 象 , 就 可 以 反 推 出 ClassObject对 象 , InterfaceObject 对 象 和 DLLFile对 象 。 根 据 XML Schema可 以 构 建 XML 文 档 树 , 对 XML 文 档 树 文 档依 次 把 的节点进行分层遍历 , 然后采用递归算 法 , XML 树上最边上的叶子转化 为方法对象哈希表 , 实 现 方 式 如 图 所 6 示 。 图 类 配 置 文 件 的 树3 XML 图 接口配置文件的 图4 schema 图 配 置 转 哈 希 表6 XML MethodObject 通用参数和动态参数组处理 4.2 对于外部的方法 , 要 传 入 参 数 , 同时也获得结 果 。 这 些 都 要用一些通用的数据结构来描述 。 参 数必须可以支持任何类 型 , 是一个通用性 的 参 数 。 通过创建一个数据的通用 类 , 可 以 保证支持任何数据类型 。 由于传入和传出 的参数有多有少 , 这就要求参数组能实 现 随意的自动增长和减少 。 通过设计一个动态自增长的参数数 组 就 可 以 实 现 。 设 计 模 型 如 图 7 表 示 。 图 接口配置文件的 树5 XML 图 类 和 类 的7 DataValueObject DynamicArrayObject 设 计 模 型 动态参数组的增加数组对象方法如下 , 图 动态装载的全过程 8 PlugPlatform DynamicArrayObject addObject(DataValueObjectobj) { public if (Objects == null) { Objects = new DataValueObject[1]; Objects[0] = obj; return this; } else { DataValueObject [] objectList = new DataValueOb- ject[Length + 1]; for (int i = 0; i < Length; i++) { objectList[i] = Objects[i]; } objectList[Length] = obj; Objects = objectList; return this;} } 动态参数组的删除数组对象方法如下 , 图 类 图9 PlugPlatform DynamicArrayObjectdeleteObject(int idx) { public 表 if (Objects == null) return this; 1 else { if (idx >= 0 && idx < Length && Length > 1) { DataValueObject [] objectList = new DataValueObject [Length 1]; - for (int i = 0; i < idx; i++) {objectList[i] = Objects[i];} for (int i = idx + 1; i < Length; i++) {objectList[i 1] = - Objects[i]; } Objects = objectList; return this; } else { if (idx == 0 && Length <= 1) { Objects = null; return this; } else return this; } } 插件平台动态装载 并 执 行}4.3 DLL , 动态调用外部方法的核心代码如下所示 PlugFramework是 整 个 PlugPlatform平 台 的 核 心 内 容 。 主 要 public object InvokeClassMethod (String className, object[] 实现检查和装载 DLL 文 件 , 动 态 创建实例化对象 , 验 证 并 执 objectArgs, String methodName, object[] methodArgs) 行 外 部 方 法 。 { Object[] newArgs = new PlugPlatform依据配置文件可以了解装 载的外部 DLL 文 件 Object[methodArgs.Length]; Object thisObject = new Object(); 所整个装载和调 用 过 程 如 图 和要求执行的类或接口方法 。 8 Type type = CreateType(className); MethodInfo[] 示 。 methods = type.GetMethods(); Object instance = 包 含 有 类 和 接 口 , 这些类和接口之间有继 PlugFramework CreateObject(type, objectArgs);foreach 承 、 实 现 、 关 联 关 系 , 如 图 9 所 示 。 (MethodInfo m in methods) { PlugFramework各个类的具体描述如 表 1。 if (m.Name == methodName) { newArgs = ConvertArgsType(m, methodArgs); 化 类 , 方法名称写错 了 , 不能执行方法等 等 。 try { if (! m.IsStatic) thisObject = m.Invoke(instance, 5 应用实例 newArgs); //非静态方法,使用类实例调用 else thisObject = m.Invoke(null, newArgs); 本例程序主要有三 个 方 面 组 成 , XML 配 置 文 件 、 外 部 return thisObject;} DLL 文 件 和 PlusPlatform调 用 代 码 。 catch (Exception e) {throw new PlusException (" 不 能 5.1 XML 配 置 文 件 动态调用方法,原因," + e.Message, e); }} 采 用 的 XML 配置文件有两个 , 一个是针对类对象 的 XML } return thisObject; 配 置 文 件 , 一个是针对接口对象的配置文 件 。 }其 中 类 对 象 的 XML 配 置 文 件 如 下 , 图 表 示 实 现 全 过 程 。 下 面分别对每个步骤 10 PlugPlatform 做一个详细描述 。 ,1, 外部应用请求动态调用 。 ,2, PlusConfig类根据配置文件创 建 PlugFactory对 象 。 ,3, PlugFactory对 象 创 建 一 个 Action对 象 。 testAction01 逆 向 产 生 ,, 对 象 获 得 对 象 组 ,Dll- 4Action MethodObject testAction02 FileObject对 象 。 testAction03 ,, 根 据 对 象 中 的 文 件 信 息 , 对 5DllFileObject DLL Action 象 通 过 AssemblyManager类 获 得 Assembly对 象 。 testAction01 , 6, Action 对 象 使 用 Assembly对 象 创 建 TypeManager对 象 。 ,7, Action对 象 传 递 MethodObject对 象 给 TypeManager对 象 。 接口对象的配 置文件与类对象配置文件基本相同 , 只 不 过 配置信息中由类换成了接口 , ,8, TypeManager对 象 可 依 据 MethodObject对 象 获 得 Clas- sObject对 象 。 并 使 用 ClassObject对 象 信息动态创建一个外部 ClassObject对 象 的 实 例 instanc。e 信 息 调 用 instance的 动 态 方 法 。 instance 把执行结果返回 给 Ac- tion 对 象 。 testAction01 文 件 内 容5.2 DLL 其 编 译 的 DLL 文 件 为 UserLibrary.dl, l 该 dll 文 件 包 括 两 个 类 和 一 个 接 口 , 其 内 部 代 码 为 , public class UserTest1 { public DynamicArrayObject testAction01 (DynamicAr- rayObject outObject) { DynamicArrayObjectthisObject=new DynamicArrayObject(); //分解 DynamicArrayObject 图 实 现 的 顺 序 图10 PlugPlatform DataValueObjectdo1 = null; string ls = null; ,10, Action对象把执行结果返回给外部应 用 。 for (int i = 0; i < outObject.Length; i++) { 其 中 Plus工厂模式采用 了 Factory模 式 。 对 于 Assembly的 do1 = outObject.getObject(i); 生 成 采 用 了 Singleton模 式 。 ls += (String)do1.getDataValue();} 4.4 异 常 处 理 DataValueObject do2 = new DataValueObject(); 由于应用程序中有 很多不可预料的问题 , 本平台在很多 地 do2.setDataType(do1.getDataType()).setDataValue(ls); //组装 DynamicArrayObjec,t返回 DynamicArrayObject 方都有可能出现人为错误 , 如找不到配置文 件 , 配 置 文 件 的 格 thisObject.addObject(do2); 式 不 对 , 不能解析配 置 文 件 , 类或接口名称写错 了 , 不 能 实 例 do2.setDataType("string").setDataValue(第二个对象"值."); return thisObject; } thisObject.addObject(do1).addObject(do2); public DynamicArrayObject testAction02 (DynamicAr- string dllFile = Application.StartupPath + "\\DllInterface- rayObject outObject) { File.xml"; return outObject; } PlugFactory factory = PlusConfig.BuildFactory(dllFile); } IAction action = factory.CreatAction(); public class UserTest2 : InterfaceTest1 { DynamicArrayObject outputObject = action.Execute("I n- public DynamicArrayObject testAction01 (DynamicAr- terfaceTest1.testAction01",thisObject); rayObject outObject) { 可 以 对 返 回 的 做 分 解 查 看 , 满 足 设 计DynamicArrayObject DynamicArrayObject thisObjec =new DynamicArrayObject(); t要 求 。 //分解 DynamicArrayObject 6 结语 DataValueObjectdo1 = null; 反射机制结合动态数 组很好地解决了应用软件的后期维护 string ls = null; for (int i = 0; i < outObject.Length; i++) { 和 升 级 。 对于应用软件 的 变 化 , 可不改动任何现有的程 序 , 只 do1 = outObject.getObject(i); 要 修 改 XML 配置文件的相应 对象名称和加载新的对象即可 , ls += (String)do1.getDataValue(); } 程序不需要任何的重编 、 重启和硬性改 动 , 并保证了原应用 系 DataValueObjectdo2 = new DataValueObject(); 统的可复用性从而实现降低耦合度 , 实现复用的目 标 。 do2.setDataType(do1.getDataType()).setDataValue(ls); 本模型在层与层之间 借助类调用和接口实现 , 利 用 反 射 机 //组装 DynamicArrayObjec,t返回 DynamicArrayObject thisObject.addObject(do2); 制把调用者与实现者在编 译 期 分 离 。 运行期通过读配置文件 动 return thisObject; 态 加 载 实 现 类 , 并 通 过 接 口将实现者强制转型 , 使 其 为 调 用 者 } 所 用 , 完成调用者和实 现 者 的 解 耦 。 但 是 , 这个功能并不是 完 public DynamicArrayObject testAction02 (DynamicAr- 全 完 善 , 对于插件平台 也 有很多的改进性 , 如果能对类和接 口 rayObject outObject){ return outObject;} 配置文件更加丰富 , 把 插 件平台升级为一个框架容器 , 该 容 器 } 能把对象之间的依赖关系 先 行 剥 离 , 然后在适当时候由容器 负 public interface InterfaceTest1 { 责产生具体的实例再注射 到 调 用 者 中 , 即控制权由应用代码 中 DynamicArrayObject testAction01 (DynamicArrayObject 转到了外部容器 , 控制权发生了转 移 。 即 所谓的控制反转模 outObject); 式 , 这 种 模 式 在 Java中 已经有比较成熟的框架 , 如 Spring等 。 } 相 信 凭 借 Microsoft.NET庞 大 的技术框架平台 , 在 C# 上 也 会 有 调 用 代 码5.3 调用代码也分为两类 , 一类是针对类对象处 理的 , 代 码 如 这样的控制反转框架出现 。 下 , 参考文献 ,美 , 等 , 康 博 译 入 门 经DynamicArrayOb- [1] Karli Watson Christian Nagel ,C# DynamicArrayObject thisObject = new ject(); 典, 北 京 , 清华大学出版 社 , 2006 ,DataValueObjectdo1 = new DataValueObject(); [2] MSDN Library .NET Framework开 发 员 指 南 , 在 运 行 时 了 解 DataValueObjectdo2 = new DataValueObject(); 类 型 信 息, 2003, do1.setDataType("string").setDataValue(" 类 测 试 , 第 一 个 对 [3] 刘 瑜 , 张 世 琨 , 王 立 福 , 杨 芙 清 . 基于构件的软件框架与 象值 .");角色扩展形态研究. 软 件 学 报 , 200 4, 14,8, , 1364-1370. do2.setDataType("string").setDataValue("第二个对象值.");[4] 段 春 笋 , 杜 立 新. C# 动态数组设计原理 . 电脑编程技巧与 thisObject.addObject(do1).addObject(do2); 维 护 , 200 5, (7) :24-25. string dllFile=Application.StartupPath+ "\\DllClassFile.xml"; [5] 何 文 海 , 谢 建 刚 . 基 于 .NET 平台的插件式 应 用 框 架 开 PlugFactory factory = PlusConfig.BuildFactory(dllFile); IAction action = factory.CreatAction(); 发 . DynamicArrayObjectoutputObject = action.Execute 电脑知识与技术 ,学 术 交 流 ,,200 7, ,8, , 755-756.[6] ("UserLibrary.UserTest1.testAction01",thisObject); 冷 山 述 , 陆 倜 , 武 装 . 用 C# 构造可复用软件体系结构 . 航 另一类是针对接口对象处理 , 代 码 如 下 , 空 计 算 技 术 , 200 3, ,4, , 88-93. [7] DynamicArrayObjectthisObject=new DynamicArrayObject(); 殷 凯 , 谢 文 威. 在 工 厂 方 法 模 式 中 .NET 反射技术应用的研 DataValueObjectdo1 = new DataValueObject(); 究. 常州工学院学报 , 2006; (4, , 28-34. [8] DataValueObject do2 = new DataValueObject(); 姚 明 , 李 家 兰. 基 于.NET的 通用软件开发平台的研究与实 do1.setDataType("string").setDataValue(" 接 口 测 试 , 第 一 个 对 现. 电脑知识与技术 (学 术 交 流), 2007; ,8, , 797-798. 象值."); ,收 稿 日 期 , 2009 年 1 月 6 日 ,
本文档为【C_创建插件业务平台】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_963767
暂无简介~
格式:doc
大小:143KB
软件:Word
页数:0
分类:生活休闲
上传时间:2018-04-05
浏览量:16