65.9K
CodeProject 正在变化。 阅读更多。
Home

创建 RapTier 模板

starIconstarIconstarIconemptyStarIconemptyStarIcon

3.00/5 (4投票s)

2003年12月15日

8分钟阅读

viewsIcon

76432

downloadIcon

706

深入探讨 RapTier 模板的设计,并演示创建自己的模板所需的步骤。

RapTier - .NET Code generation tool

引言

本文旨在深入了解 RapTier Active Templates 的内部机制,并提供一些可作为创建自己的模板的起点示例。如果您熟悉 ASP.NET 或 JSP 的基础知识,您会惊讶于只需学习很少的知识,就能开始创建自己的代码生成模板,利用 .NET 框架的所有强大功能和 C# 的灵活性。

背景

必备组件

  • .NET framework 1.0 或 1.1。请访问此链接 "如何获取 .NET Framework" 下载 .NET framework。
  • RapTier。如果您尚未安装 RapTier,请 在此处 下载。(提供免费版本)。

RapTier 是什么

RapTier 是一款基于模板的 C#、VB.NET 和 SQL 代码生成器,能够以分钟为单位开发强大而健壮的数据库驱动的 .NET 应用程序。

与其他许多使用“被动”模板、在生成过程中仅替换有限标签的代码生成工具不同,RapTier 利用了 Active Templates (AT) 技术。Active Template 是静态代码和 C# 指令的混合体,用于控制代码的生成方式。通过使用/修改现有模板或创建新模板,您可以生成满足特定开发需求的 code。

每次 RapTier 生成代码之前,Active Template Engine (ATE) 都会检查所选模板组中的任何模板文件(扩展名为 atcs 的文件)自上次编译以来是否已更新。如果找到已修改的模板文件,ATE 会将所有组模板转换为 C# 类,这些类继承自 TwoLKit.Ate.TextFileGenerator 抽象类,并将其编译为 .NET 程序集。

程序集编译完成后,ATE 会加载它,创建所需模板类的新实例,并调用 ATE 从模板代码创建的 Generate 方法。

Active Template 语法

模板文件包含以下元素的任意组合:

  • 基本输出代码(C#、VB.NET、Java、HTML、ASP.NET、SQL 等)
  • 代码块
  • 命名代码块
  • 注释

代码块

代码块用于在处理模板时定义内联代码或内联表达式。使用内联代码定义代码块或控制流块。使用内联表达式作为调用 Writer.Write 方法的快捷方式。

脚本块 描述
<# 代码 #> 定义在处理模板时执行的一个或多个代码行。
<# 代码 ##>

定义在处理模板时执行的一个或多个代码行。忽略从结束标签 ##> 开始直到行尾或任何非空白字符的所有空白字符(包括换行符)。

<#= 表达式 #> <# Writer.Write(expression); #> 的快捷方式
<#= 表达式 ##> <# Writer.Write(expression); ##> 的快捷方式

命名代码块

命名块的通用格式为 <#@ BlockName BlockSpecificData #><#@ BlockName BlockSpecificData ##>。第二种格式用于忽略从结束标签 ##> 开始直到行尾或任何非空白字符的所有空白字符(包括换行符)。

目前,模板引擎支持两种类型的命名块:ImportsInstanceMembers

@Imports 块用于导入命名空间,从而允许 C# 模板代码使用 .NET 类而不必指定完整的类名。@InstanceMembers 代码块包含模板方法和属性。它至少必须实现抽象类 TwoLKit.Ate.TextFileGenerator 中声明的 RelativeFilePath 属性。此属性指定输出文件的名称和相对位置。

注释

注释通常用于为代码添加注解以供将来参考,或使模板的一部分无效。模板引擎不处理开闭注释标签内的任何内容。

脚本块 描述
<#-- 注释掉的代码或内容 --#> 使模板的一部分无效。
<#-- 注释掉的代码或内容 --##>

使模板的一部分无效。忽略从结束标签 ##> 开始直到行尾或任何非空白字符的所有空白字符(包括换行符)。

注意:您可以在 RapTier 文档 中找到有关 Active Template 语法的更多信息。

尽管所有 Active Templates 的语法都相同,但 RapTier 使用模板文件名来区分 5 种不同类型的模板。

  • Database_XYZ.atcs - 在接收到 IDatabase 作为 Database 环境变量时调用一次。
  • Table_XYZ.atcs - 为数据库模型中的每个表调用一次。调用此方法时,RapTier 会将 ITable 作为 Table 环境变量传递。
  • Procedure_XYZ.atcs - 为数据库模型中的每个存储过程或函数调用一次。调用此方法时,RapTier 会将 IStoredProcedure 作为 Procedure 环境变量传递。(自 RapTier 1.4 起)
  • DirectoryInfo.atcs - 用于控制位于 DirectoryInfo.atcs 所在目录(及其所有子目录)中的所有模板的代码生成。
  • XYZ.atcs - RapTier 不直接调用此类模板。它们用于存储其他模板使用的共享静态方法和属性。

示例模板

在学习了 Active Templates 的理论基础之后,我们将进入实践部分。让我们创建一个模板,用于生成一个简单的 HTML 文档来展示数据库架构。

要创建新模板,请打开 <RapTierRootDirectory>/Templates 目录,并为您的模板组创建一个新目录,例如 SimpleDbDoc。之后,创建 Template.config 文件。

文件结构必须如下所示:

接下来打开 Template.config 并将以下代码复制到其中。

<?xml version="1.0"?>
<TemplateConfig>
        <Id>RapTierTutorial.SimpleDbDoc</Id>
        <Name>Simple DbDoc Template</Name>
        <Description>Simple DB documentator.</Description>
        <References>
            <Reference>TwoLKit.Ate.dll</Reference>
            <Reference>TwoLKit.nTierBuilder.Api.dll</Reference>
        </References>
</TemplateConfig>

其中

  • Id - 唯一模板 ID
  • Name - 模板显示名称
  • Description - 可选模板描述
  • References - 模板脚本使用的“非标准” .NET 程序集列表。

通常,Template.config 文件只包含两个引用:TwoLKit.Ate.dllTwoLKit.nTierBuilder.Api.dll。模板引擎使用这些引用将模板文件编译为 .NET 程序集。

现在,让我们创建第一个模板。本示例中的模板将生成 Default.htm 文件,该文件显示指向包含基本表信息的 HTML 页面的链接列表。

首先,我们将创建一个名为 Database_Default.atcs 的文本文件,并将以下代码输入其中。您可以使用本文提供的源代码。

Database_Default.atcs

<html>
    <head> 
        <title><#= Database.CodeName #></title> 
    </head> 
    <body> 
        <h4><#= Database.CodeName #></h4> 
        <ul> 
        <# // Iterates through the collection of the table columns 
        foreach(ITable table in Database.Tables) 
        { ##> 
            <li><ahref="<#= table.Name#>.htm"><#=
            table.Name #></a></li> 
        <# } ##> 
        </ul> 
    </body> 
</html> 
                 
<#-- 
The code below imports namespaces and 
declares methods and properties that are 
used by the template only. This code will 
not be copied into the output file.    
--##> 
                 
<#@ Imports 
using System; 
using TwoLKit.nTierBuilder.Api.DbDom; 
/* We need to import this namespace for IDatabase, 
    ITable and other DB DOM interfaces */ 
##> 
                 
<#@ InstanceMembers 
        // Every template must override the RelativeFilePath 
        // property to return the name of the output file 
        public override string RelativeFilePath 
        { 
            get { return "Default.htm"; } 
        } 
    
        // We don't have to create this property,
        // however it simplifies the template code
        // and allows i.e. using <#= Database.CodeName #>
        // instead of <#= 
        //((IDatabase)Environment["Database"]).CodeName #> 
        private IDatabase Database 
        { 
            // RapTier sends IDatabase as the
            // Database environment variable 
            get { return (IDatabase)Environment["Database"]; } 
        } 
##>

正如您所见,代码的顶部混合了基本输出文本(在本例中为 HTML)和 C# 代码。之后,我们添加了一个可选的注释块。然后是两个代码块 @Imports@InstanceMembers

其次,我们需要创建一个模板来生成显示表和视图详细信息的 HTML 页面。创建一个文件并命名为 Table_TableInfo.atcs。之后,输入以下代码并保存更改。

Table_TableInfo.atcs

<html>
        <head>
            <title><#= Table.Name #></title>
        </head>
        <body>
            <h4><#= Table.Name #> Columns</h4>
            <ul>
<#            foreach(IColumn column in Table.Columns)
                { ##>
                    <li><#= column.Name #> (<#= column.DbType #>)</li>
<#            } ##>
            </ul>
        </body>
    </html>
        
<#--
The code below imports namespaces and 
declares methods and properties that are 
used by the template only. This code will 
not be copied into the output file.
--##>
    
<#@ Imports
using System;
using TwoLKit.nTierBuilder.Api.DbDom; 
/* We need to import this namespace for 
IDatabase, ITable and other DB DOM interfaces */
##>
    
<#@ InstanceMembers
            // Every template must override the RelativeFilePath
            // property to return the name of the output file
            public override string RelativeFilePath
            {
                // Dynamically create the name of the output file
                get { return Table.Name + ".htm"; }
            }
    
            // We don't have to create this property,
            // however it simplifies the template code
            // and allows i.e. using <#= Database.CodeName #> instead of
            // <#= ((IDatabase)Environment["Database"]).CodeName #>
            private ITable Table
            {
                get { return (ITable)Environment["Table"]; }
            }
##>

现在,您已准备好测试您的第一个 RapTier 模板。只需运行 RapTier,连接到数据库(支持的数据库:MS SQL Server、MSDE、MS Access、Oracle、MySQL),在 Template Group 组合框中,选择 SimpleDbDoc 模板项,然后从 Project 菜单中选择 Generate Code 菜单项。

成功生成后,在 Internet Explorer 中打开生成的项目。您刚刚创建了第一个 RapTier 模板并生成了一个数据库驱动的应用程序!

高级模板功能

  • Enabled 属性

    Enabled 属性控制模板是否启用。默认值为 true

  • RewriteExistingFile 属性

    RewriteExistingFile 属性在 TwoLKit.Ate.TextFileGenerator 中声明,用于控制 RapTier 是否重写已存在的文件。此属性可以在模板中被覆盖。默认值为 true

  • 数据库对象扩展属性

    RapTier 1.x 模板通过 IDatabase 接口的扩展属性接收大部分代码生成设置。

    RapTier 支持以下 IDatabase 扩展属性:

    • TargetIDEProperty - 目标 IDE 代码。具有以下值之一:VSNET2002VSNET2003BDS
    • DbEngine - 数据库引擎名称。具有以下值之一:GenericMSSQLAccessOracleMySql
    • BaseOutputDirectory - 基本输出目录路径。
    • DbTierNamespace - 所有 DB-tier 类的基本命名空间。
    • WinUITierNamespace - 所有 WinForm UI 类的基本命名空间。(自 RapTier 1.4 起)
    • WebUITierNamespace - 所有 WebForm UI 类的基本命名空间。(自 RapTier 1.4 起)
    • GenerateWinUI - 指定是否生成 WinForm UI 代码。
    • GenerateWebUI - 指定是否生成 WebForm UI 代码。(自 RapTier 1.4 起)
    • GenerateStoredProcedures - 指定是否生成存储过程。(自 RapTier 1.4 起)
    • GenerateSqlIdentity - 指定是否支持 IDENTITY 列。(自 RapTier 1.4 起)
    • Copyright - 版权文本。
  • 在模板之间传递数据

    在某些情况下,需要在多个模板之间共享数据。为此,您可以使用 Session 变量(Environment.Session[<KeyName>])。

    RapTier 按以下顺序处理模板:

    1. DirectoryInfo.atcs 模板
    2. Database_Xyz.atcs 模板
    3. Table_Xyz.atcs 模板
    4. Procedure_Xyz.atcs 模板
    5. 子目录中的模板
  • DirectoryInfo

    DirectoryInfo 模板不生成任何代码。这些模板文件用于控制 RapTier 是否处理同一目录及其所有子目录中的其他模板文件。在处理任何其他模板之前,RapTier 会检查 DirectoryInfoEnabled 属性。如果此属性返回 true,RapTier 会获取 RelativeFilePath 属性值来为所有其他模板创建基本输出目录。

结论

在本文中,我们探讨了 RapTier 模板的结构。模板中使用的类似 ASP.NET 的语法使得能够非常快速地掌握和应用这项技术。RapTier 提供的所有模板都可以“按原样”使用,或根据您的标准和需求进行扩展和定制。

为本文的目的,我尽量保持“SimpleDbDoc”模板的逻辑简单。您可以随意进一步扩展该模板,或者查看 “DbDoc” - 这个模板可以生成完整的 HTML 格式的数据库文档。

编程愉快!

© . All rights reserved.