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

上篇 已经就客户化的整体方案进行了叙述,这次主要是说明一些细节部分的设计。

类型的视图元数据

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

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

属性继承

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

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

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

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

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中的定义代码:

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;
}

使用时,也是类似:

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

小结

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

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

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏北京马哥教育

Python自动化运维之高级函数

一、协程 1.1 协程的概念 协程,又称微线程,纤程。英文名Coroutine。一句话说明什么是线程:协程是一种用户态的轻量级线程。(其实并没有说明白~) 那么...

351110
来自专栏安恒网络空间安全讲武堂

bugkuctf_web_writeup(部分)--下

bugkuctf平台10个较简单的web题目writeup,适合新手入门,可以找来试试http://ctf.bugku.com/bbs 。 本地包含 题目描述:...

49530
来自专栏Java后端技术栈

Java虚拟机值对象访问以及如何使用对象的引用(2)

对象访问在 Java 语言中无处不在,是最普通的程序行为,但即使是最简单的访问,也会却涉及 Java 栈、 Java 堆、方法区这三个最重要内存区域之间的关联关...

7710
来自专栏Golang语言社区

Golang语言社区--【基础知识】入门

Go语言入门 1. 简介 本文是关于Go编程语言的基础教程,主要面向有C/C++基础的读者。它并不是一个语言的完整指南,关于 Go的具体细节请参考 语言规范 ...

34950
来自专栏linux系统运维

原 shell脚本中的逻辑判断,文件目录属

28750
来自专栏marsggbo

python3编码问题终结者--还搞不懂你来找我

python unicode bytes str 编码 首先需要说明一下,该篇文章是以python3为基础的,python2是否适合没有验证过。 由于pytho...

84390
来自专栏Kevin-ZhangCG

[ Java面试题 ]WEB篇

22480
来自专栏desperate633

深入理解Java多线程(multiThread)多线程的基本概念线程同步wait,notify,notifyAll线程的生命周期

一个java程序启动后,默认只有一个主线程(Main Thread)。如果我们要使用主线程同时执行某一件事,那么该怎么操作呢? 例如,在一个窗口中,同时画两排...

14520
来自专栏测试驿栈

JMeter(十)-正则表达式关联

jmeter中,接口自动化的关键在于参数关联。比如需要登录的接口,如何调用登录口令?一个增删改查的闭环,如何将接口参数上下传递?下面就以实际的例子来仔细说一说

15420
来自专栏决胜机器学习

​PHP开发过程的那些坑(五) ——PHP的empty()

PHP开发过程的那些坑(五)——PHP的empty() (原创内容,转载请注明来源,谢谢) 一、遇到的问题 PHP的empty不是一个函数,而是一个语言结构,用...

33160

扫码关注云+社区

领取腾讯云代金券