专栏首页哲学驱动设计基于OEA框架的客户化设计(三) “插件式”DLL

基于OEA框架的客户化设计(三) “插件式”DLL

    本篇主要描述GIX4项目中如何把单独的模块设计为一个“插件”,如何把它组装到系统中。至于为什么加引号,之后会有说明。

原理

    在基于产品线开发时,7,2,1的产品功能分类中,20%的功能是需要在产品线主干中包含进来的。这些功能一般会被设计为“可选包”。在某一客户版本产品的装配阶段,在“可选包”集合中挑选需要的功能,进行组装,得到最终的产品。具体内容,见:《软件产品线工程方法:如何在OpenExpressApp做客户化工作》。

    在基于OpenExpressApp框架的GIX4项目中,“合同”模块就是属于这20%的功能,它被设计为独立的DLL,在产品装配时为需要的客户进行装配。

DLL间的关系

    项目中,实际的开发项目如下图:

图1 解决方案结构图

    其中,红色区域的两个项目就是合同模块对应的实体类项目和WPF界面项目。它们都属于“产品721”中的“2”。(最上面的Customizing文件夹中的项目,都是属于各分支的客户版本独有的内容,属于“产品721”的中“1”。)合同包与主干包的关系如下:

图2 合同包与主干包的关系

    合同模块中,带有合同信息的预算类ContractBudget从主干版本中的预算书类Budget中继承下来,作为新的聚合根对象(此概念,参见:《DDD》)。

动态加载DLL

    在产品线工程的开发中,需要动态加载的DLL,是上述的“721”中的“2” 和“1”。

    OEA框架中,使用MEF作为插件框架。(详见金根的:《.Net4下的MEF(Managed Extensibility Framework) 架构简介》)。所有DLL中,实现了IModule接口的

按照约定,把GIX4.Contract.Library.dll 和 GIX4.Contract.Module.WPF.dll 两个dll分别放置到Library和Module文件夹下,框架会自动加载所有的实体类型及其对应的元数据,并按照元数据的内容使用AutoUI模块进行展示。

    客户特定的模块,则需要放置在客户各自的文件夹中。这在《基于OEA框架的客户化设计(一) 总体设计》中已经谈过。框架会根据当前的产品定义,进行DLL加载。

    把合同包放到项目指定的文件夹中后,按照OEA框架中的元数据信息进行标注的聚合根对象,都会显示在左边的模块列表中,在合同模块中,包含了以下几个根对象:合同模板、合同科目、合同预算导入、合同经济指标。运行界面如下图:

图3 加入合同模块后的软件运行界面

自定义视图

    一个独立模块的设计,不会考虑用户是否真的需要其所有的功能。在把它组装进产品后,很可能需要对它进行一些定制。例如,在合同模块的DLL放到产品中后,框架自动加载所有类型并显示,这就导致现在的ContractBudget类和原有的Budget类同时显示出来了。这里我们其实是要用ContractBudget完全替换Budget类,所以,我们需要在产品定义中,把Budget类完全隐藏:

protected override UIInfo DefineUI()
{
    var ui = base.DefineUI();

    ui.Entity<Budget>().UnVisible();
    ui.Entity<ContractBudget>().Visible();

    return ui;
}

可以看到,这个定义是直接依赖了合同模块DLL的,也就是说,合同模块不是真的插件,而是在产品编译期已经知道必须包含这个DLL。所以目前只是做到编译期选择装配,而不是运行时动态插入新的DLL,这就是为什么一开始说合同模块并不是真正的插件的原因了。

总结

    到本篇为止,客户化的内容已经基本说明。一些其它的问题为以单独的文章说明(例如:实体类继承方式的重构),关注OEA的朋友可以继续关注一下。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • OEA 中 WPF 树型表格虚拟化设计方案

        最近用 OEA 做的仓库管理系统中,许多界面的都需要使用表格控件来显示数据。一是这些表格的列非常多,有的甚至达到了 200 列,而且一个模块的界面中可能...

    用户1172223
  • Rafy 领域实体框架 - 树型实体功能(自关联表)

    在 Rafy 领域实体框架中,对自关联的实体结构做了特殊的处理,下面对这一功能进行讲解。 场景 在开发数据库应用程序时,往往会遇到自关联表的场景。例如,分类信息...

    用户1172223
  • 月度计划工具 0.3.14.0 发布

    2011 年已经发布过一套《个人管理工具集》,其中有计划模板和一些常用小工具组。时隔一年半,一直在用的月度计划模板感觉对个人管理非常有效,所以基于 “OEA框架...

    用户1172223
  • JavaScript:你可以赞扬批评嘲讽它,但却无法忽略

    兼容表 :http://kangax.github.io/compat-table/es6 ?

    前朝楚水
  • 详细设计写些啥

    详细设计是相对概要设计而言的,是瀑布开发流程的一个重要环节,在概要设计的高层设计的基础上,从逻辑上实现了每一模块的功能,是编码阶段的主要参考资料,是从高层到低层...

    三哥
  • Nginx 更多模块详解(十)

    ngx_http_auth_basic_module模块 详细说明请参考官网 地址链接

    咻一咻
  • 搭建自己的技术博客系列(五)hexo博客接入busuanzi插件,展示访问量和网站运行时间

    <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js">

    黄小斜
  • 软件开发生命周期的五个阶段

    一个软件从定义,开发,运行维护,直到最终要经历一个时期的过程 ,这个时期称为软件的生命周期 系统软件生命周期一般为分析,设计,实现和测试与维护这几个阶段,

    北京锐智互动
  • Spring Aop标签解析原理详解

    对于Spring Aop的实现,是非常复杂的,其实现过程主要包含xml标签的解析,切面表达式的解析,判断bean是否需要应用切面逻辑,以及使用Jdk代理或者是...

    用户4143945
  • 【面试宝典】进程和线程知识

    面试官:刚毕业是吧? 小白:是的。 面试官:问你一个简单的问题吧,进程和线程的区别? 小白:进程是正在运行的程序,线程是进程中的一个执行单元。 面试官:(⊙o⊙...

    程序员互动联盟

扫码关注云+社区

领取腾讯云代金券