首页 > 技术文章 > Netsharp总体设计

Netsharp 2014-04-27 17:12 原文

阅读本文请先阅读如下两篇文章

  1. 什么是企业软件
  2. Netsharp什么

Netsharp总体设计

1.1     Netsharp终端形式

Netsharp基于.NET平台,支持的产品形态有三种:

  1. 北极熊(Polarbear,桌面模式,WPF实现)
  2. 熊猫(Panda,BS模式,纯HTML)
  3. 先锋(Pioneer,移动Web模式,基于Panda)

Netsharp是三种终端的全集,本文介绍的内容多以北极熊作为例子,因为北极熊功能最多、最强、最稳定。

三种形态都是前端,她们公用同一套后端,后端指的是业务服务器之后包括的功能。

 

1.2     Netsharp部署类型

Netsharp有五种部署类型,分别对应五种部署的场景:

 

类型

名称

说明

Desktop

桌面客户端

仅仅包括界面层、实体、接口以及前后端公用的程序集

通过互联网与服务器端交互

Server

业务服务器端

作为业务服务器,对外通过互联网公布服务接口

处理复杂的业务逻辑功能

可以做集群(暂不支持)

Desktop_Server

传统的CS结构

桌面客户端和业务服务器在同一个进程内,主要方便开发调试;单人操作的系统,或者并发要求不高的,可以使用此种模式。

WebFront

WEB前端

Web前端服务器也是服务器,但是只负责处理界面的渲染等逻辑,不处理业务逻辑,业务逻辑通过调用业务服务器的接口来完成

Web前端服务器与业务服务器多在同一个局域网

Web前端服务器与业务服务器分开一般出于安全和性能的考虑

Web前端服务器与业务服务器分开更易于Web前端服务器做集群

WebFront模式需要管理多个Session,Desktop模式只需要管理一个Session

WebFront_Server

WEB前端+业务服务器

Web前端服务器与业务服务器在同一进程内

 

Netsharp的部署类型,可以通过bin/Netsharp.Light.exe进行设置,下图是部署类型的设置方式:

 

1.3     Netsharp平台管理

本章节介绍Netsharp的六个核心概念,他是Netsharp基础,这六个概念都有对应的工具支持,从工具角度上对平台的资源进行有效、清晰的管理。

这六个概念并不是Netsharp的全部内容,本节也不是介绍Netshrap的技术架构,而是介绍Netsharp平台是如何管理开发人员的成果的。 

1.3.1  插件

    插件框架是越来越流行的一种开发方式。插件做的比较好的常见于IDE,如Eclipse(基于OSGI标准)、Netbean、SharpDevelop。国内一款软件(OSGI.NET)实现了.NET平台的OSGI标准,算是做得比较规范的。除此之外笔者没有见过国内其他的比较正规的插件体系,大部分声称系统支持的所谓插件都是伪插件,从技术角度来说不过是工厂模式加根据配置反射创建对象而已。笔者认为插件系统有三个必须要素:

  1. 插件,一个插件有多个路径;插件从物理上可脱离产品独立存在
  2. 扩展点(Netsharp叫路径),扩展点可以横穿多个插件
  3. 插件项支持多种类型,如菜单、类型、图标等。插件项类型本身也有扩展点。

 

Netsharp的插件设计参考了SharpDevelop,SharpDevelop是一个IDE工具,有些地方并不适应于企业软件,Netsharp在SharpDevelop的基础上进行了如下的改造和扩展:

  1. 支持数据库配置,而非xml配置
  2. 路径支持继承和重写
  3. 插件项支持权限控制
  4. 提供可视化界面编辑插件项

Netsharp提供了可视化工具对插件管理,管理工具支持两种视角,插件视角和路径视角:

1.3.2  实体模型

在企业软件开发中,实体模型主要指的是实体的模型,模型一般通过UML图的方式表现,比较直观的表达问题域的静态结构关系,这种图是分析设计所关心的。而对于平台来说,关心的是做一个UML静态类图工具出来,更关心的是实体模型本身自描述的元数据信息,本文称之为实体元数据。

平台有了实体元数据,业务开发的序幕就此拉开,这个过程可以时髦的称之为“领域驱动”,不过跟常说的“领域驱动”稍有不同。基于实体元数据配合平台工具可以做的事情有:

  1. 生成数据库对象,包括表结构、索引、主键、约束、外键等
  2. 实体类代码
  3. 持久层的ORM映射元数据
  4. 自动生成接口、服务、业务类、界面控制器的类
  5. 自动生成报表、表单、列表、查询的界面元数据
  6. 可以做字段权限控制、数据权限控制
  7. 可以做单据编码规则
  8. 其他

 

    关于Netsharp的实体设计,请参见管理软件实体设计

1.3.3  Netsharp资源

1.3.3.1 什么是资源

资源是Netsharp创造的概念,资源包括两个方面,资源树和资源类型,其中资源树也可称之为资源节点。

 

如何理解资源我们从考察如下两个场景开始:

要素

商贸企业

软件开发公司

角色

公司员工

软件开发人员

工具

供应链管理系统(SCM)

Netsharp

数据类型

销售订单、发货单、发票、出库单等等

列表、表单、查询、报表

数据举例

3月1号销售给客户A总金额100W

3月1号给客户A发货

3月2号销售给客户B总金额120W

3月1号开发销售订单列表,编辑列表元数据

3月1号开发销售订单表单,编辑表单元数据

3月2号开发销售发票列表,编辑列表元数据

结论

SCM是工具,用来管理订单、发货单等数据

Netsharp是工具,用来管理列表、表单、报表的元数据。

 

上述两个场景放在一起考察,他们的不同之处在于是不同的行业,干的不同的事情。相同的地方都是使用一个工具来管理自己工作中使用的数据。开发人员的数据就是工作区、列表、表单、报表等数据,Netsharp中把开发维护的这些数据叫资源。这些数据是有不同的类型,SCM的每种类型(销售销订单、发货单、销售发票等)的数据叫单据;Netsharp中的每种类型(作区、列表、表单、报表等)叫资源类型

1.3.3.2 资源是如何管理的

资源和插件是相互补充的,插件和资源都是平台的工具,区别在于,插件强调插件物理可插拔、路径可扩展、插件项支持多种类型,但是其插件项的类型只能是携带信息比较少的类型,比如菜单。对于一些复杂的类型,比如工作区或者列表元数据,则需要强类型的结构来表达,这种情况插件表达则不太合适,资源就是解决这种问题的,而且资源还有自己的视角。Netsharp的平台工具中,大部分菜单都是使用资源进行管理的,可以说资源的概念比插件的概念要大。

 

Netsharp中有30种以上的资源类型,这些资源类型按照树状结构进行分类,资源的分类叫资源树,树上的每个节点叫资源节点。Netsharp中所有的资源类型的分类是统一的,即所有的资源分类都使用一个资源树。资源节点在Netsharp中对应的实体是Netsharp.Core.ResourceNode。下图是Netsharp的平台管理工具的面板,他可以通过工作区的主菜单”视图/平台工具”打开,这些工具中大部分是以资源的方式来进行管理的。

 

以Netsharp部件工作区(PartWorkspace)为例,部件工作区是一种资源,他按照资源树的方式进行管理,请参见下图部件工作区的工具。

 

下图是Netsharp的枚举管理工具,枚举是Netsharp的一种资源,他也按照资源树的方式进行管理,请参见下图:

 

1.3.3.3 资源是如何分类的

下图是Netsharp资源节点的管理界面,所有的资源节点组成了一棵资源树。

 

对于管理软件来说,一般会进行如下分类

级次

一级

二级

三级

四级

五级

本文命名

产品线

子系统

模块

领域对象

实体

ERP产品线

建筑施工企业软件产品

子系统一

-

-

-

子系统二

-

-

-

子系统三

-

-

-

...

-

-

-

ERP产品

供应链

采购

采购订单

采购订单头

 

采购订单行

 

结算明细

进货单

-

采购发票

-

...

-

销售

-

-

库存

-

-

财务

现金

-

-

往来

-

-

出纳

-

-

生产

-

-

-

分销零售

-

-

-

....

-

-

-

 

上图为稍微复杂一些的系统分级结构,简单的系统可能只有第三、四、五级。第五级别的实体为研发人员视图。客户和销售人员不会有此概念,或者概念比较模糊,即他们不会把实体作为独立的概念环境进行思维。在命名上会有歧义的是第三级和第四级,即模块和领域对象。“领域对象”是本文的一种叫法,目前还没有找到更好的进行第三级和第四级进行区分的命名。使用“领域对象”的初衷是领域指的是软件给客户(某一种岗位在某一个业务场景)提供完整业务的一种最小的场景,如录入一张新的采购订单,在这个场景中,用户打开采购订单界面,可以做很多与采购订单编辑相关的事情。(这个名称感觉也不是很好,因为用户很难理解)模块可以简单的理解为是一个部门级别的应用,或者为一个需要多个岗位来完成的场景,比如采购管理。

 

在Netsharp的资源节点对应的实体是Netsharp.Core.ResourceNode,ResourceNode有个属性ResourceType,ResourceType是一个枚举,有三个可选值:分类、插件、单据。ResourceType是资源节点的必输字段。下面详细介绍这三种资源节点类型。

1.插件

和第三级模块对应,当资源节点类型为插件是,必须在资源节点上设置对应的插件。因为平台的资源是通过资源树管理的,当插件进行导出操作时候,平台会根据插件对应的资源节点把下属的所有资源进行导出,插件的安装、卸载也是这种逻辑。

2.单据

和第四级(领域对象)对应,当资源节点是一个领域对象时,如销售订单、采购入库单等,资源节点类型选择单据。当资源节点为单据时,必须设置资源节点的EntityId。EntityId是Netsharp中常用的概念,他表示一个领域对象,技术上对应领域对象(或者叫实体)的Type.FullName,也可以理解为实体模型的类全名,参见下图:

 

领域对象是实体的特例,当一个资源节点和一个实体对应时,类型都可以选择单据。

3.分类

当资源节点类型不为插件和单据时,都可以选择分类。

1.3.4  工作台

Netsharp工作台就是最终用户看到的产品的主界面,工作台有时也称之为门户。用户可以自定义工作台的布局,下图显示了默认工作台的布局结构:

 

下面是这六个部分的概要描述

顺序

名称

说明

插件路径

扩展说明

1

LOGO

产品图标

自动读取应用程序配置的产品名称

2

用户信息区

 

Workbench/StatusBar/RightMenu

 

3

MainMenu

主菜单

Workbench/MainMenu

Netsharp的原则是主菜单只现实系统级别的菜单(如系统选项、常用工具、视图、帮助等),不显示业务相关的菜单

4

Pad

面板

Workbench/Pad

目前平台提供了四个面板,导航栏、平台工具、业务模型、作业管理;在这个路径下可以创建自定义的导航面板,

5

Workspace

工作区

工作区一般会通过面板和主菜单的出发打开,不在赘述。Netsharp支持扩展自定义的工作区。

6

StatusBar

状态栏

 

 

除了上面六个部分,还有不明显体现在界面元素上的工作台初始化相关工作项,他们分别:

 

顺序

名称

说明

插件路径

扩展说明

1

Autorun

工作台初始化

Workbench/AutoRun/Client

工作台启动后,会读取此路径,自动执行此路径配置的逻辑

2

Icon

图标

Netsharp/Icons

自定义的图标在这里初始化

3

Homepage

起始页

Workbench/Homepage/ZonePart

Netsharp目前的起始页是有多个Zone组成的,这里可以设置起始页的Zone

4

VersionCache

版本缓存

为了提高性能,把Netsharp的元数据缓存在本地,当元数据改变时自动更新缓存的机制

5

 

 

 

 

6

 

 

 

 

 

1.3.5  部件工作区

上文已经介绍了工作区(Workspace)的的概念,本节介绍一种特殊的工作区叫部件工作区(PartWorkspace),无论您是Netsharp的最终用户,还是开发人员,您时刻都会跟PartWorkspace有关。

 

本人认为软件的界面是一种树状的逻辑结构,在设计模式中对应着组合模式(Composite),以Netsharp的工作台为例,工作台是顶级节点,工作台由工作台页头、Pad容器、工作区容器、主菜单、状态栏等子组件组成,这几个子级别又分别有自己的子级组件,如此类推就形成了一棵树。树的末级节点一般是Textbox、ComboBox等控件。所以一般基于元数据的界面描述都使用XML格式的语法,因为XML是树状结构的,比如HTML和XAMAL。

 

一般来说,开发人员封装的界面组件,分成两个种,一种是技术性质的控件,比如Outlookbar,日历等;另一种是业务性质的控件,比如订单表单,和单据控件,不同的研发团队积累不一样,封装的角度也不同,如果封装单据作为控件的话,是平台化的思路,抽象层次要高一些。Netsharp是平台所以会对单据进行封装,但是Netsharp封装的力度比单据要细一个级别,本文称之为部件。一个工作区是由多个部件组成的,部件之间一般有父子关系。对于订单的表单来说,其工作区一般由两个部件组成:实体的表单部件(父)和实体明细列表部件(子)。对于订单列表来说,界面可以有三个部件:订单列表(父)、订单表单(子)、订单子表(子或者孙,父亲为列表或者表单),子表部件和表单部件可以被重用,做出更多灵活的界面。部件对于做界面设计和二次开发都提供了比较好的角度,可以说是技术和业务上最理想的封装粒度。

 

Netsharp提供了20种部件,用户可以继承扩展这些部件,也可以实现自己独立的部件,Netsharp部件参考下图:

 

序号

编码

名称

默认控制器

默认工具栏

说明

1

EntityList

列表.主列表

Netsharp.Commerce.EntityListPart

Netsharp/Commerce/EntityList/Toolbar

 

2

Datagrid

列表.只读

Netsharp.Commerce.DatagridPart

Netsharp/Commerce/Datagrid/Toolbar

 

3

EntityDetail

列表.单据列表

Netsharp.Commerce.EntityDetailPart

Netsharp/Commerce/EntityDetail/Toolbar

 

4

VoucherDetail

列表.单据明细列表

Netsharp.Commerce.VoucherDetailPart

Netsharp/Commerce/Voucher/DetailMenu

 

5

Detail

列表.细列表

Netsharp.Commerce.DetailPart

Netsharp/Commerce/Voucher/DetailMenu

 

6

DatagridSolution

列表方案

Netsharp.Commerce.DatagridSoltionPart

Netsharp/Commerce/QuerySolution/MainMenu

 

7

ReportList

列表.报表

Netsharp.Commerce.DatagridReportPart

Netsharp/Commerce/Voucher/DatagridReportMenu

 

8

VoucherForm

表单.单据

Netsharp.Commerce.VoucherFormPart

Netsharp/Commerce/Form/Navigation/Toolbar

 

9

CustomerForm

表单.可保存

Netsharp.Commerce.FormPart

Netsharp/Commerce/Form/Edit/Toolbar

 

10

FormPart

表单.属性

Netsharp.Commerce.FormPart

Netsharp/Commerce/Form/Property/Toolbar

 

11

ReferencePart

表单.引用表单

Netsharp.Commerce.ReferencePart

Netsharp/Commerce/Voucher/ReferenceMenu

 

12

ReportStatistics

报表.统计表

Netsharp.Grus.SummaryReportPart

Netsharp/Commerce/Datagrid/Toolbar

 

13

ReportRdlc

报表.交叉表

Netsharp.Grus.RdlcReportPart

Netsharp/Grus/RdlcReport/Toolbar

 

14

ReportGrus

报表.GRUS

Netsharp.Grus.GrusPart

 

 

15

ReportQueryFilter

报表查询条件

Netsharp.Commerce.RdlcQueryFilterPart

Netsharp/Commerce/QueryFilter/MainMenu

 

16

ReportSolution

报表方案

Netsharp.Grus.ReportSolutionPart

Netsharp/Grus/ReportSolution/Toolbar

 

17

TreePart

分类树

Netsharp.Commerce.TreePart

Netsharp/Commerce/CategoryTreePart/Toolbar

 

18

QuerySolution

查询方案

Netsharp.Commerce.QuerySolutionPart

Netsharp/Commerce/Solution/MainMenu

 

19

QueryFilter

查询条件

Netsharp.Commerce.QueryFilterPart

Netsharp/Commerce/QueryFilter/MainMenu

 

20

Customer

自定义

 

 

 

 

1.3.6  六驾马车

Netsharp有六驾马车的概念,这六驾马车都基于插件使用,可以拥有非常强大的功能。六驾马车是从技术角度对开发六种场景抽象,他们分别是:

 

编号

英文名

中文名

说明

场景

开发相关

1

Command

命令

界面操作的一个触发,常用的有Button、MenuItem、Toolbar的事件

系统点击“退出”按钮,执行Netsharp.Platform.ApplicationExitCommand

界面层使用,一般和菜单、树节点、工具栏项上配置

2

Trigger

字段触发器

某一个字段被修改之后,引起其他字段的计算

修改单价和数量时,自动计算金额

重写实体的OnPropertyChanged方法

实现IPropertyTrigger接口

界面层Controller中的On**Changed方法

3

Validation

字段验证

数据合法性验证

保存时的邮件验证

实体属性Set调用时捕获的异常信息实现接口IPropertyValidation

4

Condition

字段条件

某个字段在某种场景下不可以编辑或者隐藏

审核后数量不能修改

重写实体的Condition方法

实现接口IPropertyCondition

界面层Controller的**Condition方法

5

OperationCondition

操作条件

操作按钮在某个场景下不可用或者隐藏

审核后不能删除

实现接口IOperationCondition

在插件中配置

6

Action

(无)

一个实体的操作分成多个步骤执行,每个步骤叫一个Action。

界面客户端和服务端都可以使用Action

客户端和服务端都可以使用,参见下文

实现接口IAction

在插件中配置

服务端的路径为服务类型全名+方法名

客户端的路径为控制器类型全名+方法名

 

 

本文是体系结构的介绍,关于每驾马车在第三个系列Netsharp开发中都会有详细的介绍,这里只说明一下Action在界面端和服务端的两个种:

一、客户端Action场景:

例如,在Netsharp平台的普通的一张表单界面上,用户执行保存按钮时,执行的是Controller的Save方法,按照顺序执行的逻辑如下:

 

顺序

功能

Action

说明

1

调用前置方法OnSaving

OwnerMethodAction

 

2

调用前置事件Saving

OwnerEventAction

 

3

性能跟踪开始

StopwatchStartAction

 

4

显示Loadingbar

LoadingbarStartAction

 

5

界面端录入合法性校验

FormpartSaveAssertAction

 

6

调用保存服务

FormpartSaveAction

 

7

调用保存后置事件Saved

OwnerEventAction

 

8

调用保存后置方法OnSaved

OwnerMethodAction

 

9

隐藏Loadingbar

LoadingbarEndAction

 

10

性能跟踪停止

StopwatchEndAction

 

 

二、服务端Action场景

例如,在订单保存时服务方法中执行的逻辑,按照顺序如下:

 

顺序

功能

Action

说明

1

信用控制

 

 

2

可用量控制

 

 

3

最低售价控制

 

 

4

订单基本校验

 

 

5

订单持久化到数据库

 

 

6

生成收款单

 

 

7

生成出库单

 

 

8

生成加工单

 

 

9

记往来账

 

 

10

记可用量帐

 

 

11

更新客户信用

 

 

12

更新最低售价

 

 

1.4     Netsharp组件清单

分类

组件

功能特征

客户可见

工具支持

4.0版本已支持

元数据管理方式

1

实体模型

可持久化

可序列化

实体支持三驾马车

平台自定义数据类型

平台提供常见的若干父类(可持久化实体、业务实体、分类实体)

支持字段扩展

可视化实体设计

 否

UML建模工具

插件

2

插件机制

参考SharpDevelop插件机制(改造成适合管理软件的插件模式)

数据库格式

路径支持继承

插件项支持重写

支持插件项与功能权限绑定

 否

插件编辑工具

插件浏览工具

安装卸载工具

插件

3

持久层

多数据库

级联对象增删改查

OQL查询

并发控制

引用检查

基于Ado.net的事务

分布式事务(暂不支持)

支持Sqlserver

部分支持Mysql

可扩展支持Oracle

可扩展支持其他数据库

 否

OQL查询分析器

4

分布式

服务调用级别事务

多种访问方式(HTTP\TCP)

高性能的序列化

客户端动态代理

日志跟踪

根据父类的实体默认提供服务实现如:EntityService、BusinessEntityService、VoucherService

 否

 性能跟踪查看其

5

工作台

支持自定义布局

默认布局支持Pad、Workspace、主菜单、状态来自定义配置

支持产品名、公司版权、LOGO、版本等自定义设置

登录界面支持自定义背景图片

 是

 

插件和配置文件

6

单点登录

 暂不支持

 是

 

7

多国语言

 基于数据库配置

平台提供多语言工具

 是

 多语言维护工具

资源树

8

并发

 基于Ts的并发控制

根据系统选项确定是否并发控制

 否

 实体元数据上设置

实体模型

9

互斥

 两个业务场景不能同时发生

 否

 

资源树

10

表单

根据实体元数据快速生成表单

支持最终用户的字段设置

支持常见的控件类型

数据的双向绑定

字段显示,必输,可空,公式等设置

默认打印

 是

 表单管理工具

资源树

11

列表

根据实体元数据快速生成列表

支持最终用户的字段设置

支持常见的控件类型

数据的双向绑定

支持分页

支持懒加载

可设置字段:显示,必输,可空,排序,汇总等属性

支持默认打印

 是

 列表管理工具

资源树

12

查询

根据实体元数据快速生成查询

支持最终用户的字段设置

支持常见的控件类型

多种查询控件

自定义查询方案

 是

 查询工具

资源树

13

打印

可视化打印模板设置

支持汇总表

支持交叉表

支持自定义报表

图表(暂时不支持)

 是

 报表设计器

报表工具

资源树

14

权限控制

功能权限/字段权限

数据权限

权限约束/权限互斥

分级授权

 是

 操作管理工具

资源树

15

编码规则

支持流水号

支持编号包含普通文本

3.         支持编号包含当前实体字段

 是

 编码规则设置工具

资源树

16

AOP

 暂不支持

 否

 

17

性能统计分析

 自动

 否

 性能统计选项开关

性能分析器

18

自动化测试

 暂不支持

 否

 

19

脚本引擎

 支持C#脚本功能

 否

 脚本测试工具

20

UI控件套件

使用Telerik控件库

自定义若干控件

 是

 

21

业务选项

 基于插件的选项配置

默认提供多种数据类型的选项控件

 是

 插件工具

插件

22

向导

 支持向导框架

 是

 

23

组织机构

支持用户/角色

支持多组织

支持总公司/子公司/部门/分类/项目/职务/岗位

 是

 

24

界面三驾马车

状态控制

触发器

编辑验证

 是

 

硬编码

插件

界面元数据

25

工作流

 

 是

 

资源树

26

创建帐套

 暂不支持

 是

 

27

异常管理

 异常框架

异常跟踪

异常查看

 否

 异常列表查看

资源树

28

枚举

 表单、列表、查询对应的控件

自动生成枚举代码

 是

 枚举管理工具

资源树

29

参照

支持下拉列表

支持弹出参照

支持表单、列表、查询动态创建默认参照

支持添加自定义的过滤条件

支持添加当前行的变量作为条件

支持C#脚本生成条件

 是

 参照管理工具

资源树

30

预警/提醒/通知

 

插件工具配置

资源树

31

作业

基于Quartz.NET

支持可视化的触发器设置

可视化创建作业

支持作业日志跟踪

作业管理工具

资源树

32

日志组件

 

 否

 生成日志文件

33

客户端自动升级

客户端发现新版本时自动升级

 

 

 

34

数据库脚本升级工具

低版本到高版本升级时,自动执行若干脚本

 

 

 

 

35

缓存

内存缓存

缓存服务器

单个对象缓存

SET缓存

 

 

 

 

36

Session管理

超时验证

踢出管理

 

 

 

37

业务日志

单据增删改查自动记录日志

登录等操作自动记录日志

日志查看、跟踪

 

 

 

38

导出SQL脚本

列表、表单支持导出当前数据位SQL脚本

支持导出当前数据及组合数据

支持根据ById导出

支持导出全表

支持任意SELECT语句的脚本导出

 

 

 

单据、列表的二次开发菜单

SQL查询分析器

 

1.5     Netsharp发展路线图

Netsharp路标规划分成五个阶段,参见下图,目前基本完成第二个阶段,即平台产品化阶段。

  

 

本文特别感谢东莞许胜平的建议和校对工作。

推荐阅读