博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于OEA框架的客户化设计(二) 元数据设计
阅读量:6336 次
发布时间:2019-06-22

本文共 2743 字,大约阅读时间需要 9 分钟。

类型的视图元数据

    基于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还是应该在以场景驱动、以客户为主的思想前提下进行设计。

本文转自BloodyAngel博客园博客,原文链接:http://www.cnblogs.com/zgynhqf/archive/2010/09/26/1835336.html,如需转载请自行联系原作者

你可能感兴趣的文章
陈松松:视频营销成交率低,这三个因素没到位
查看>>
vmware nat模式原理探究,实现虚拟机跨网段管理
查看>>
JavaSE 学习参考:集合运算
查看>>
【Signals and Systems】 SYLLABUS
查看>>
RH135-2-command-line-interface
查看>>
浅谈OS
查看>>
mac下开启docker API远程调用
查看>>
tar 命令的详解
查看>>
Cisco路由器安全配置
查看>>
第十次作业
查看>>
给定一个字符串s,返回去掉子串"mi"后的字符串。
查看>>
Nginx 外的另一选择,轻量级开源 Web 服务器 Tengine 发布新版本
查看>>
Wrod中超链接的一些技巧
查看>>
IP_VFR-4-FRAG_TABLE_OVERFLOW【cisco设备报错】碎片***
查看>>
Codeforces Round #256 (Div. 2) D. Multiplication Table 【二分】
查看>>
ARM汇编指令格式
查看>>
HDU-2044-一只小蜜蜂
查看>>
HDU-1394-Minimum Inversion Number
查看>>
[转] createObjectURL方法 实现本地图片预览
查看>>
JavaScript—DOM编程核心.
查看>>