CodeSmith 的业务对象
通过为业务对象进行代码生成,可以节省开发大型应用程序的时间。
引言
开发大型应用程序时,开发人员面临的最大挑战之一是维护设计标准和方法。在编程的黄金时代,设计文档、编码标准和代码审查是开发人员唯一可用的工具。随着 CodeSmith 等代码生成器的出现,开发团队现在拥有了一个强大的工具,可以加快开发过程并在整个应用程序中保持标准。在开发应用程序时,模板可以通过使用通用的设计模式来生成不同的业务对象,从而为您节省大量时间。根据定义,模板是可重复的模式,可以从任何设计方法派生。在代码生成中使用模板的好处是能够强制执行设计方法和标准,同时为任何应用程序节省开发成本。本文将介绍一种基本设计模式和用于生成该设计模式代码的模板。
业务对象设计模式
业务对象包含反映数据的属性;您会发现对象命名为发票、发票明细等。通常,它们包含嵌入式关系 -- 例如,一个发票对象可能有一个检索该发票实例明细的属性。
基于这个简单的观察,我们可以为我们的业务对象制定设计标准
- 业务对象包含属性
- 业务对象需要集合
- 业务对象需要访问数据
业务对象
业务对象类模板 (ClassGenerator.cst) 用于创建业务对象的属性和方法。将为 XML 文档中定义的每个对象生成一组标准的访问对象数据的方法。将为每个定义的业务对象创建以下方法
公共静态方法
CreateNewObject
:创建新的Object
。DeleteObject
:删除Object
。
公共实例构造函数
Object
- 重载。初始化Object
类的新实例。
公共实例方法
Copy
:复制Object
。Delete
:删除Object
。Fetch
:获取Object
。Save
:保存Object
。Update
:更新Object
。
业务对象集合
业务对象集合模板 (CollectionGenerator.cst) 用于为每个业务对象创建集合类。集合对象使用 'CollectionBase
' 作为基类。将为每个定义的业务对象创建以下方法
公共实例构造函数
ObjectCollection
:构造函数初始化ObjectCollection
类的新实例。
公共实例属性
Count
:获取CollectionBase
实例中包含的元素数量。Item
:获取或设置与指定键关联的值。
公共实例方法
Add
:将项添加到 Object Collection。Contains
:确定 Object Collection 是否包含指定的Object
。IndexOf
:确定 Object Collection 中特定项的索引。Insert
:将项插入到 Object Collection 中指定的位置。Remove
:从 Object Collection 中移除Object
的第一次出现。
受保护实例方法
OnInsert
:在将新的Object
插入到 Object Collection 之前进行验证。OnRemove
:在从 Object Collection 中移除新的Object
之前进行验证。OnSet
:在将Object
设置到 Object Collection 中之前进行验证。OnValidate
:在验证Object
时执行其他自定义过程。
业务对象数据
业务对象数据类模板 (DataClassGenerator.cst) 用于定义每个业务对象的数据访问层。将为每个定义的业务对象创建以下方法
公共实例构造函数
ObjectData
:构造函数初始化ObjectData
类的新实例。
公共实例方法
CreateNewObject
:在数据库中创建新的Object
。DeleteObject
:从数据库中删除Object
。FetchObject
:从数据库获取单个Object
。UpdateObject
:在数据库中更新Object
。
基类对象
业务对象基类模板 (BaseObjectClass.cst) 用于为每个业务对象创建基类。以下是每个业务对象使用的属性
公共实例属性
Id
:业务对象的 ID。Name
:业务逻辑对象的名称。
内部
GenerateObjectId
:为给定对象生成 ID。
基类数据对象
业务对象基数据类模板 (BaseDataClass.cst) 用于为每个业务对象创建基类。以下是每个业务对象使用的属性
公共实例构造函数
BaseDataClass
:构造函数初始化BaseDataClass
类的新实例。
公共实例属性
ConnectionString
:从配置文件获取连接字符串配置。
公共实例方法
AddParamToSQLCmd
:向SqlCommand
添加参数。ExecuteCollectionReader
:从 SQL 数据读取器返回一个对象集合。ExecuteObjectReader
:从 SQL 数据读取器返回一个对象。ExecuteReaderCmd
:从 SQL 数据读取器生成对象集合。ExecuteScalarCmd
:执行查询。SetCommandType
:将CommandText
属性设置为存储过程的名称。
数据层生成器
数据层模板 (DataGenerator.cst) 用于创建支持业务对象所需的数据库对象。
流程
Object_Create
:在数据库中创建新的Object
。Object_Delete
:从数据库中删除Object
。Object_Fetch
:从数据库获取单个Object
。Object_Update
:在数据库中更新Object
。
使用生成器
基于 XML 文档提供的定义,生成器将为您的业务对象、业务对象集合、业务对象数据访问、业务对象表和存储过程生成代码。
业务对象属性
attribute |
映射到 |
remarks |
|
table |
名称将代表表名 |
|
列 |
名称将代表列名 |
类属性
attribute |
remarks |
|
代表表名 |
属性属性
attribute |
remarks |
|
代表列名 |
|
代表系统类型或业务对象集合 |
|
支持的类型
C# 类型 |
映射到 SQL 类型 |
|
|
|
|
|
|
|
|
|
|
定义业务对象
让我们创建一个简单的发票业务对象。发票对象将包含客户姓名、发票日期、发票付款状态和行项目。以下 XML 文档定义了这些对象
<?xml version="1.0" encoding="utf-8" ?>
<BusinessObjects xmlns="http://www.austinconnergroup.com">
<class name="Invoice">
<properties>
<property name="Id" type="String" maxSize="36" />
<property name="Customer" type="String" maxSize="96" />
<property name="InvoiceDate" type="DateTime" maxSize="" />
<property name="InvoicePaid" type="bool" maxSize="" />
<property name="InvoiceDetails" type="InvoiceDetailCollection" maxSize="" />
</properties>
</class>
<class name="InvoiceDetail">
<properties>
<property name="Id" type="String" maxSize="36" />
<property name="InvoiceId" type="String" maxSize="36" />
<property name="LineItem" type="Int" maxSize="" />
<property name="ItemDescription" type="String" maxSize="96" />
<property name="ItemCostPerUnit" type="Single" maxSize="" />
<property name="ItemQuanity" type="Int" maxSize="" />
<property name="ItemUnit" type="String" maxSize="8" />
</properties>
</class>
</BusinessObjects>
在我们的定义文档中,我们定义了两个对象,Invoice
和 InvoiceDetail
。您会注意到 Invoice
对象包含一个 InvoiceDetails
属性,其类型为 InvoiceDetailCollection
。这定义了 InvoiceDetail
和 Invoice
之间的关系,并将生成该关系所需的相应方法和 SQL 语句。
运行生成器
一旦有了模型,我们就可以生成代码了。BuildTemplate.cst 是为所有业务对象生成代码的主入口点,它具有以下属性
XmlFile
- 将从中生成类的 XML 文档。OutputDirectory
- 代码输出的基目录。GenerateBaseClasses
- 设置为true
以生成基类。RootNamespace
- 生成类将属于的根命名空间。ObjectNamespace
- 生成类将属于的对象命名空间。BusinessLogicNamespace
- 生成类将属于的业务对象命名空间。DataAccessNamespace
- 生成类将属于的数据对象命名空间。DeveloperName
- 开发人员姓名。CompanyName
- 公司名称。
关注点
本文介绍了为概念验证而开发的原型。在编写了生成器和支持模板后,我对结果感到非常惊叹,立即为我们的团队编写了模板并将其部署到我们的生产环境中。最大的好处不仅在于节省了时间,还在于所有生成的代码都是自文档化的。仅仅这一点就值了创建这些模板的努力。我每天面临的最大挑战是缺乏文档化的代码,现在这变得轻而易举。
历史
- 2004 年 11 月 23 日 - 初始文章。