基于OEA框架的客户化设计(二) 元数据设计

类型的视图元数据

    基于OEA框架的GIX4项目中,客户化工作主要是对各客户版本中类型的视图信息进行定义。下图是包含这些类型的类图:

图1 客户化API中的类型视图元数据

 



 

属性继承

    在应用程序定义中,需要支持继承类型的视图信息定义,也就是说,在基类上定义的视图信息,子类在没有定义的情况下,直接使用基类的定义;当然,也可以为具体的子类做特殊的定义。

    但是,TypeViewInfo是某一个实体类型的视图信息,它只对应唯一一个Type。所以要支持继承定义,需要做一些特殊的处理。

    一种方案是为所有TypeViewInfo建立父子关系,然后在获取属性值时,再按照继承线进行检索。这种方案类似于WPF中的依赖属性,不过这就意味着TypeViewInfo中所有属性的实现都不能再使用一般的.NET属性,编码起来比较复杂,代价太大。

    我们在这里选用的方案比较简单,就是在所有视图信息定义完成之后,在框架内部对所有类型的值进行合并。如果某一类型自己没有定义某个值,而基类已经定义了,则直接把基类的值设置到该类型上。这种方法比较简单,而且由于这个合并的操作是在所有定义完成之后进行的,所以不需要对每个属性都进行更改,可以使用一般的.NET属性。但是,它有以下缺点:合并操作比较耗时;在合并操作前(如在定义的时候),不支持继承属性的获取。即如果这时获取某类型的定义时,并不包含父类的属性定义。不过由于比较简单,而且估计以后的使用场景也不会遇到刚才所说的情况,所以最后我们还是采用了这种方式。随便贴些代码:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

public abstract class ViewInfoBase : DefinitionAtom

{

    private string _label;

 

    /// <summary>

    /// 显示在视图上的“标签”

    /// </summary>

    public virtual string Label

    {

        get

        {

            return this._label;

        }

        internal set

        {

            this.CheckUnFrozen();

            this._label = value;

        }

    }

 

    /// <summary>

    /// 和基类的视图信息进行合并。

    ///

    /// 在基类上定义的视图信息,如果这个基类的子类没有显式设置其它的值,则会使用基类的视图信息定义。

    /// </summary>

    /// <param name="baseDef"></param>

    internal virtual void MergeBaseClassDef(ViewInfoBase baseDef)

    {

        MergeDef(ref this._label, baseDef._label);

        MergeDef(ref this._isVisible, baseDef._isVisible);

    }

 

    /// <summary>

    /// 合并属性值。

    /// 如果子类没有显式设置其它的值,则会使用基类的值。

    /// </summary>

    /// <typeparam name="T"></typeparam>

    /// <param name="current"></param>

    /// <param name="baseValue"></param>

    protected static void MergeDef<T>(ref T current, T baseValue)

        where T : class

    {

        if (current == null && baseValue != null)

        {

            current = baseValue;

        }

    }

}



 

应用程序定义API

    之前我说过,当客户版本比较多时,定义的东西会比较多,所以客户化框架设计的目标之一就是API要尽量的简单、易用、可读。这里我们特意对API的使用方式进行了特别的设计:

  1. 使用强类型的方式来查找类型或进行定义。
  2. 使用Lambda Expression来进行强类型的属性的查找或定义。
  3. 方便连续为多个属性进行赋值。方式类似Web开发中的JQuery框架和.NET中的StringBuilder类。

    仔细看了上篇文章的朋友可能注意到了,在Common.AppDefinition中的定义代码:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

protected override UIInfo DefineUI()

{

    var ui = base.DefineUI();

 

    ui.Entity<CBFGQBQItemTitle>()

        .EntityProperty(t => t.Code).ShowInLookup().ShowInList().Set_ListMinWidth(200);

 

    ui.Entity<ContractBudget>()

        .Association(cb => cb.CBMeasureItemTitles).UnVisible();

 

    ui.Command(CCN.CopyBudgetCommand)

        .Set_ToolTip("复制一条预算书").Set_Label("复制预算书").Visible();

 

    return ui;

}

使用时,也是类似:


1

2

3

4

5

bool isVisible = ui.Entity<CBFGQBQItemTitle>().EntityProperty(t => t.Code).IsVisible;

if (isVisible)

{

    //..........

}

 



 

小结

    本篇已经把OEA中客户化设计中的主要内容讲完了,包括如果支持继承类型的视图信息定义、客户化配置API的设计。下一篇会写一下GIX4项目中客户化的一个应用实例:合同模块以插件的方式动态装配,并支持界面的自定义。

    PS:最后学习了EF CTP4,发现它的配置API与我们的设计不谋而合,极为相似。虽然实现起来相对比较繁琐,但是API还是应该在以场景驱动、以客户为主的思想前提下进行设计。

时间: 2024-10-06 04:48:31

基于OEA框架的客户化设计(二) 元数据设计的相关文章

基于OEA框架的客户化设计(一) 总体设计

设计目标 支持实体类的扩展. 支持实体扩展包的动态加载. 支持界面扩展及界面扩展包的动态加载. 各版本间自定义界面元素,可以基于现有的特定版本修改一些内容. 各版本间支持自定义内容文件,如果没有使用,则使用默认版本的内容文件.(内容文件是指:图片.帮助文档等.)     解释一下,基于OEA框架的GIX4项目是以领域实体为中心的架构.主版本中的领域实体,代表了产品功能"7.2.1"中的7和2 .7是所有版本都应该有的领域实体,2是可以进行配置以说明是否具备的领域实体,而1就是在主干之外

OEA 框架中集成的 RDLC 报表介绍

之前 OEA 一直用着一个 Delphi 开发的报表,所以两年来我一直就想在 OEA 中构建一个纯 .NET 的报表模块,但是一想到要开发复杂的报表引擎和设计器就觉得麻烦.所以这事一直拖着.最近开始研究一些成熟的报表引擎,经过对比,还是发现微软的 RLDC 报表已经能满足我大多数需求.其中包括表格.矩阵.图表 等复杂控件,同时同样的报表格式在 B/S 模式下也可以直接使用,最新的 Tablix 控件非常灵活,能实现大多数表格样式.所以我决定不再费时费力去造一个轮子,而是直接把微软的 RDLC 报

基于Bootstrap的Metronic框架实现条码和二维码的生成及打印处理操作_javascript技巧

在很多项目里面,对条形码和二维码的生成和打印也是一种很常见的操作,在Web项目里面,我们可以利用JS生成条形码和二维码的组件有很多.本文引入两个比较广泛使用的JS组件,用来处理条形码和二维码的生成处理,并介绍如何利用CLODOP组件实现内容的打印输出. 生成条形码使用组件JsBarcode,生成二维码使用组件qrcodejs. 1.条形码的生成 条码的作用一般在一些商品标签上,方便使用条码枪快速.准确录入信息. 如下所示是一种条形码   这里条形码生成使用了JsBarcode组件进行处理,它支持

AForge.NET是一个专门为开发者和研究者基于C#框架设计的视频录像

原文:AForge.NET是一个专门为开发者和研究者基于C#框架设计的视频录像 AForge.NET是一个专门为开发者和研究者基于C#框架设计的,他包括计算机视觉与人工智能,图像处理,神经网络,遗传算法,机器学习,模糊系统,机器人控制等领域.这个框架由一系列的类库组成.主要包括有:AForge.Imaging -- 日常的图像处理和过滤器AForge.Vision -- 计算机视觉应用类库AForge.Neuro -- 神经网络计算库AForge.Genetic -进化算法编程库AForge.M

基于AJAX的动态树型结构的设计与实现

ajax|动态|设计|树型结构 <B>摘 要</B>:简要介绍了一种通用的,动态树型结构的实现方案,该方案基于Asynchronous JavaScript and XML,结合Struts框架设计实现了结构清晰.扩展性良好的多层架构,数据存储于数据库,结合XML描述树的节点信息,使得任何按预定的XML文档描述的信息都可以通过动态树来展现.<br /><table border="0" cellspacing="0" cel

针对SaaS应用程序的基于Hibernate框架的数据库分片

针对 SaaS 应用程序的基于 Hibernate 框架的数据库分片 SaaS 正在改变设计.构建.部署和操作应用程序的方式.开发一个 SaaS 应用程序与开发一个通用企业应用程序之间的关键区别在于,SaaS 应用程序必须是多租户的.其他关键 SaaS 需求,比如安全性.定制.面向服务的架构(SOA)和集成,也影响 SaaS 应用程序架构. 多租户是指应用程序在单一代码库内寄存多个承租者并共享数据库等架构的能力.有多种设计选项可启用多租户数据架构 - 每个承租者的专用数据库.每个承租者的共享数据

基于s/c的数据库查询系统的设计 ,毕业论文的题目 ,理不清思路。麻烦各位大神给个指导

问题描述 基于s/c的数据库查询系统的设计 ,毕业论文的题目 ,理不清思路.麻烦各位大神给个指导 建立一个数据库,并查询,这个好办.但是一加前面的条件就不太明白了.s/c也大致了解,但是这两个要怎么联系到一起呢.好晕啊.我是急着写论文,这些知识只学了皮毛,问题描述如果那里说错了还请担待.我只求一个大体的思路.帮帮忙吧,各路大神们. 解决方案 其实也就是让一个程序是客户端,里面跑着TCP客户端的程序,然后通过TCP连接到你的一个TCP的服务器 这些TCP的程序在网上很多,如果就是想做个毕设可以直接

OEA 框架演示 - 快过原型的开发

OEA框架经过几次较大的重构后,已经慢慢地变得成熟.     09年末.10年初的时候,我们发布了<OEA1.0>.至今也一年多了,中间我们并没有发布它最新的源码.所以有些朋友问到是不是这个框架已经停止开发了.     那么今天呢,我个人录制了一个简单的视频,来说明一下,OEA目前的使用方法,有兴趣的朋友也可以了解一下这个框架当前的进展.       视频中,我简单地录制了如何做一个小型的<图片管理系统>.我先随便列举几点 OEA 目前做到的功能: 快过原型:在理解领域模型的基础上

基于云计算的设备远程故障诊断中心的设计与实现

基于云计算的设备远程故障诊断中心的设计与实现 南京理工大学 葛二灵 本文在研究了云计算的相关理论.特点和关键技术后,结合上述存在的问题,引入了"故障诊断云"的概念,将企业设备故障数据的存储和对其进行的计算都集中于"云"中.由此设计了一种B/C(Brower/Cloud-Center)架构的设备远程故障诊断系统(相对于传统的C/S和B/S),阐述了该系统的总体组成和工作原理.并在对开源云计算平台Hadoop的核心技术HDFS.MapReduce.HBase和设备远程故