如果要在 Visual Studio 中生成程序代码或其他应用程序资源,遵守以下一般准则可能非常有帮助。 它们并不是一成不变的规则。

设计时 T4 模板准则


设计时 T4 模板是在设计时在 Visual Studio 项目中生成代码的模板。 有关更多信息,请参见使用 T4 文本模板生成设计时代码

生成应用程序的可变部分。

对于在项目期间可能更改的应用程序部分,或将在不同版本的应用程序之间更改的应用程序部分,代码生成最为有用。 可将这些可变部分与较固定的部分相分离,以便更容易确定必须生成的内容。 例如,如果应用程序提供了一个网站,则可将提供功能的标准页面与逻辑(定义从一个页面到另一个页面的导航路径)相分离。

对一个或多个源模型中的变量部分进行编码。

模型是一个文件或数据库,每个模板都可以读取该文件或数据库以获取待生成代码可变部分的特定值。 模型可以是数据库、自己设计的 XML 文件、图或域特定语言。 通常,一个模型用于在 Visual Studio 项目中生成许多文件。每个文件都是从单独的模板生成的。

可以在一个项目中使用多个模型。 例如,可以定义一个模型用于在不同网页之间导航,同时定义一个单独的模型用于设置页面布局。

应使模型关注用户的需求和词汇,而不是关注您的实现。

例如,在网站应用程序中,您将希望模型引用网页和超链接。

理想情况下,应选择适合该模型所表示信息类型的表示形式。 例如,通过网站的导航路径模型可以是一个包含框和箭头的图。

测试生成的代码。

使用手动或自动测试来验证结果代码是否按用户所需的方式工作。 避免从生成代码的同一模型生成测试。

在某些情况下,可以直接对模型执行常规测试。 例如,可以通过编写测试确保网站中每个页面都可从其他任何页面导航到达。

允许自定义代码:生成分部类。

除生成的代码外,还允许手动编写的代码。 能够解决可能出现的所有变体情况的代码生成架构并不常见。 因此,添加或覆盖一些生成的代码属正常情况。 生成的材料以 .NET 语言(如 Visual C# 或 Visual Basic)表示时,下面两种策略特别有用:

  • 生成的类应是分部类。 这允许您在生成的代码中添加内容。

  • 类应成对生成,一个类继承自另一个类。 基类应包含所有生成的方法和属性,派生类只能包含构造函数。 这样便可以使用手写代码覆盖任何生成的方法。

在其他生成的语言(如 XML)中,使用 <#@include#> 指令对手写内容和已生成内容进行简单组合。 在较复杂的情况下,可能必须编写后处理步骤将已生成的文件与任何手写文件组合起来。

将通用材料移动到包含文件或运行时模板中

若要避免在多个模板中重复类似的文本和代码块,请使用 <#@ include #> 指令。 有关更多信息,请参见 T4 包含指令

还可以在单独的项目中生成运行时文本模板,然后从设计时模板调用它们。 为此,请使用 <#@ assembly #> 指令访问单独项目。 例如,请参见 "Inheritance in Text Templates" in Gareth Jones’ Blog(Gareth Jones 的博客中的“文本模板中的继承”)。

考虑将大的代码块移到单独的程序集中。

如果您有大的代码块和类功能块,则将此代码中的一些移到您在单独项目中编译的方法中可能会很有用。 可以使用 <#@ assembly #> 指令访问模板中的代码。 有关更多信息,请参见 T4 程序集指令

可以将方法放置在模板可继承的抽象类中。 抽象类必须从 Microsoft.VisualStudio.TextTemplating.TextTransformation 继承。 有关更多信息,请参见 T4 模板指令

生成代码,而不是配置文件

编写可变应用程序的一种方法是编写接受配置文件的通用程序代码。 以这种方式编写的应用程序非常灵活,并且可以在业务需求变化时重新配置,而无需重新生成应用程序。 但是,该方法的一个缺点是应用程序的执行效果不如更具针对性的应用程序。 而且,其程序代码也更难以读取和维护,一部分原因是它必须始终处理最通用的类型。

与此相反,在编译之前生成可变部分的应用程序可以是强类型的。 这样,编写手写代码并将其与软件的已生成部分集成将更容易,也更可靠。

若要发挥代码生成的全部优势,请尝试生成程序代码而不是配置文件。

使用生成的代码文件夹

将这些模板和生成的文件放入一个名为“生成的代码”的项目文件夹中,明确指出这些是不应直接编辑的文件。 如果创建自定义代码以覆盖或添加到生成的类中,请将这些类放入一个名为“自定义代码”的文件夹中。 一个典型的项目结构如下所示:

复制

MyProject
Custom Code
Class1.cs
Class2.cs
Generated Code
Class1.tt
Class1.cs
Class2.tt
Class2.cs
AnotherClass.cs

运行时(预处理)T4 模板准则


将通用材料移到继承的模板中

可以使用继承在 T4 文本模板之间共享方法和文本块。 有关更多信息,请参见 T4 模板指令

还可以使用具有运行时模板的包含文件。

将大型代码体移到分部类中。

每个运行时模板都生成一个与模板名称相同的分部类定义。 可以编写包含同一类的另一个分部定义的代码文件。 还可以此方式将方法、字段和构造函数添加到该类。 可以从模板中的代码块调用这些成员。

这样做的优点是更容易编写代码,因为可以使用 IntelliSense。 另外,您可以在表示形式和基础逻辑之间实现更好的分离。

例如,在 MyReportText.tt 中:

The total is: <#= ComputeTotal() #>

MyReportText-Methods.cs 中:

private string ComputeTotal() { ... }

允许自定义代码:提供扩展点

考虑在 <#+ 类功能块 #> 中生成虚拟方法。 这样单个模板可以用于许多上下文中,而无需修改。 您可以构造提供最少附加逻辑的派生类,而不是修改模板。 派生类可以是常规代码,也可以是运行时模板。

例如,在 MyStandardRunTimeTemplate.tt 中:

复制

This page is copyright <#= CompanyName() #>.
<#+ protected virtual string CompanyName() { return ""; } #>

在应用程序的代码中:

复制

class FabrikamTemplate : MyStandardRunTimeTemplate
{
protected override string CompanyName() { return "Fabrikam"; }
}
...
string PageToDisplay = new FabrikamTemplate().TextTransform();

所有 T4 模板的准则


将数据收集与文本生成分离

请尽量避免将计算与文本块混合。 在每个文本模板中,使用第一个 <# 代码块 #> 来设置变量并执行复杂的计算。 从第一个文本块往下到模板的末尾或第一个 <#+ 类功能块 #>,请避免长表达式,还要避免循环和条件(除非它们包含文本块)。 这种做法可使模板更容易读取和维护。

不要为包含文件使用 .tt

使用不同文件扩展名,例如对于包含文件,使用 .ttinclude。 仅对要作为运行时或设计时文本模板处理的文件使用 .tt。 在某些情况下,Visual Studio 将识别 .tt 文件并自动设置它们的属性以便处理。

将每个模板作为固定原型启动。

编写要生成的代码或文本的示例,并确保其正确。 然后将其扩展名更改为 .tt,并增量插入通过读取模型修改内容的代码。

考虑使用类型模型。

虽然可以为模型创建 XML 或数据库架构,但创建域特定语言 (DSL) 可能会很有用。 DSL 具有以下优点:生成类来表示架构中的每个节点以及生成属性来表示特性。 这意味着可以根据业务模型编程。 例如:

复制

Team Members:
<# foreach (Person p in team.Members)
{ #>
<#= p.Name #>
<# } #>
考虑为您的模型使用关系图。

许多模型都是以文本表的形式来最有效地显示和管理,特别是它们非常大时。

然而,对于某些类型的业务需求,阐明复杂的关系和工作流集非常重要,而关系图是最适合的媒体。 关系图的优点是方便与用户和其他利益干系人一起讨论。 通过在业务需求级别从模型生成代码,可使您的代码在需求变化时更加灵活。

UML 类和活动图可以经常为这些目的而进行调整。 您还可以将自己的关系图类型设计为域特定语言 (DSL)。 可以从 UML 和 DSL 生成代码。 有关更多信息,请参见 建立应用程序模型建立应用程序模型

Windows Live Tags: 文本模板编写准则

Blogger Labels: 文本模板编写准则

T4 文本模板编写准则的更多相关文章

  1. 编写 T4 文本模板

    文本模板由以下部件组成: 1)指令 - 控制模板处理方式的元素. 2)文本块 - 直接复制到输出的内容. 3)控制块 - 向文本插入可变值并控制文本的条件或重复部件的程序代码. 指令: 指令是控制模板 ...

  2. 使用 T4 文本模板生成设计时代码

      使用设计时 T4 文本模板,您可以在 Visual Studio 项目中生成程序代码和其他文件. 通常,您编写一些模板,以便它们根据来自模型的数据来改变所生成的代码. 模型是包含有关应用程序要求的 ...

  3. T4文本模板转换过程

    T4文本模板转换过程将文本模板文件作为输入,生成一个新的文本文件作为输出. 例如,可以使用文本模板生成 Visual Basic 或 C# 代码,还可以生成 HTML 报告. 有三个组件参与这一过程: ...

  4. 一个简单的代码生成器(T4文本模板运用)

    说要写这篇文章有一段时间了,但因为最近各方面的压力导致心情十二分的不好,下班后往往都洗洗睡了.今天痛定思痛,终于把这件拖了很久的事做了.好,不废话了,现在看看"一个简单的代码生成器" ...

  5. T4文本模板

    <#...#> 可以包含语句 <#=...#>  用于表达式,提供“输出”操作 <#+ ...> 使用类功能控制块向文本模板添加方法.属性.字段,必须作为文件中最后 ...

  6. MVC开发T4代码生成之一----文本模板基础

    T4文本模板 T4全写为Text Template Transformation Toolkit,是一种编程辅助工具,用来使程序代码自(懒)动(猿)生(福)成(利)的工具.MVC开发中大量使用了T4模 ...

  7. C#代码生成工具:文本模板初体验 使用T4批量修改实体框架(Entity Framework)的类名

    转自:http://www.cnblogs.com/huangcong/archive/2011/07/20/1931107.html 在之前的文本模板(T4)初体验中我们已经知道了T4的用处,下面就 ...

  8. T4((Text Template Transformation Toolkit))模版引擎之基础入门 C#中文本模板(.tt)的应用

    1 关于C#中文本模板(.tt)的简单应用https://blog.csdn.net/zunguitiancheng/article/details/78011145 任何一个傻瓜都能写出计算机能理解 ...

  9. T4模板之文本模板

    网址:https://docs.microsoft.com/en-us/visualstudio/modeling/design-time-code-generation-by-using-t4-te ...

随机推荐

  1. IOS UINavigationController 操作相关集合

    1.修改中间Title字体以及大小 [self.navigationController.navigationBar setTitleTextAttributes:[NSDictionary dict ...

  2. Ubuntu下命令行cd进不了/home/用户目录

    输入命令:cd /home/usr后和刚刚进入终端一样,其实已经进入了usr中,终端默认用usr用户登录,输入ls就可以查看usr目录下的文件

  3. char[]数组与char *指针的区别

    char[]数组与char *指针的区别 问题描述 虽然很久之前有看过关于char指针和char数组的区别,但是当时没有系统的整理,到现在频繁遇到,在string,char[], char *中迷失了 ...

  4. 通过SQL进行远程访问

    通过SQL语句访问远程数据库 1.得建立链接服务器:  --删除链接服务器 if exists(select * from master.dbo.sysservers where isremote=0 ...

  5. 使用MATLAB生成模糊控制的离线查询表

    1.打开模糊控制工具箱,编辑输入输出变量的隶属度函数和模糊控制规则,如下图所示,导出为fuzzy_control.fis文件. 2.打开Simulink模块,建立下图所示的系统框图,两输入,一输出,处 ...

  6. Multiple reportviewers on one page With reportviwer 11.0

    Hi,  evreryone: When I use  VS 2012  to create report with reportviwer 11.0, I  meet a  problem abou ...

  7. 搭建linux下teamspeak3多人语音服务器

    最近项目中新的需求,需要支持多人在线实时通话.就安装测试一下teamspeak.http://www.teamspeak.com/ 主页有服务器版本和客户端版本供下载安装.软硬件环境: melot@m ...

  8. work-10

    0. 问题描述 见老师博客 1.架构简介 经过软件工程的课程,我将学到的很多知识应用到了这次作业中首先,我从架构上来讲解下我的这次作业. 由于各个语言优势不相同,例如在C++课上我们讲到了C++的尴尬 ...

  9. Hibernate关联关系之双向1—n

    •双向 1-n 与双向 n-1 是完全相同的两种情形 •双向 1-n 需要在1的一端可以访问n的一端,反之依然. 测试实例代码: 实体类: package com.elgin.hibernate.nt ...

  10. Storm ui 展示字段说明

    1.Storm ui 首页 主要分为4块: Cluster Summary,Topology summary,Supervisor summary,Nimbus Configuration,如下图所示 ...