文本模板由以下部件组成:

1)指令 - 控制模板处理方式的元素。

2)文本块 - 直接复制到输出的内容。

3)控制块 - 向文本插入可变值并控制文本的条件或重复部件的程序代码。


指令:

指令是控制模板处理方式的元素,为模板转换引擎提供说明。

T4文本模板指令包括:    T4模板指令;  T4参数指令;  T4输出指令;  T4程序集指令;  T4导入指令;  T4包含指令;  T4 CleanUpBehavior 指令及其自定义指令。

指令的语法如下所示:

<#@ DirectiveName [AttributeName = "AttributeValue"] ... #>

  • []:表示为可选参数

  • DirectiveName:指令名
  • AttributeName:特性名
  • AttributeValue:特性值(特性值必须放在双引号内,如果值本身包含引号,则必须使用 \ 字符对这些引号进行转义。)
【指令通常是模板文件或包含的文件中的第一个元素。 不应将它们放置在代码块 <#...#> 内,也不应放置在类功能块 <#+...#> 之后。】

T4模板指令:

<#@ template [language="VB"] [hostspecific="true|TrueFromBase"] [debug="true"] [inherits="templateBaseClass"] [culture="code"] [compilerOptions="options"] [visibility="internal"] [linePragmas="false"] #>

  1. 模版指令中所有特性均为可选的。
  2. langeuage:输出语言,有效值C#、VB,默认为C#。
  3. debug:是否启用调试,有效值true、false,默认为false。特别说明下这个调试真的不咋地,很容易让VS崩溃,很鸡肋的功能。
  4. hostspecific:有效值true、false,默认为false。如果将此特性的值设置为 true,则会将名为 Host 的属性添加到由文本模板生成的类中。 该属性是对转换引擎的宿主的引用,并声明为Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost。
  5. inherits:可以指定模板的程序代码可以继承自另一个类,这个类也可以从文本模板生成。目前木有使用过,基本上可以忽略。
  6. compilerOptions:有效值为任何有效的编译器选项。基本上可以忽略 。

T4 参数指令:

<#@ parameter type="Full.TypeName" name="ParameterName" #>

  1. type:有效值是传递参数的类型名。

  2. name:传递参数的名。

T4 输出指令:

<#@ output extension=".fileNameExtension" [encoding="encoding"] #>

比较重要的指令,用于设置输出文件的后缀名和文件编码。

  1. extension:输出文件扩展名,默认为".cs"。

  2. encoding:文件编码。

T4 程序集指令:

<#@ assembly name="[assembly strong name|assembly file name]" #>

  1. 程序集指令相当于VS里面我们添加程序集引用的功能,该指令只有一个参数name,用以指定程序集名称,如果程序集已经在GAC里面注册,那么只需要写上程序集名称即可,如<#@ assembly name="System.Data.dll" #>,否则需要指定程序集的物理路径。

  2. T4模版的程序集引用是完全独立的,也就是说我们在项目中引用了一些程序集,然后项目中添加了一个T4模版,T4模版所需要的所有程序集引用必须明确的在模版中使用程序集执行引用才可以。
  3. T4模版自动加载以下程序集Microsoft.VisualStudio.TextTemplating.1*.dll、System.dll、WindowsBase.dll,如果用到了其它的程序集需要显示的使用程序集添加引用才可以。
  4. 可以使用 $(variableName) 语法引用 Visual Studio 或 MSBuild 变量(如 $(SolutionDir)),以及使用 %VariableName% 来引用环境变量。介绍几个常用的$(variableName) 变量:

    $(SolutionDir):当前项目所在解决方案目录

$(ProjectDir):当前项目所在目录

    $(TargetPath):当前项目编译输出文件绝对路径

    $(TargetDir):当前项目编译输出目录,即web项目的Bin目录,控制台、类库项目bin目录下的debug或release目录(取决于当前的编译模式)

$(SolutionDir):当前项目所在解决方案目录

    $(ProjectDir):当前项目所在目录

    $(TargetPath):当前项目编译输出文件绝对路径

    $(TargetDir):当前项目编译输出目录,即web项目的Bin目录,控制台、类库项目bin目录下的debug或release目录(取决于当前的编译模式)

    举个例子:比如我们在D盘根目录建立了一个控制台项目TestConsole,解决方案目录为D:\LzrabbitRabbit,项目目录为

    D:\LzrabbitRabbit\TestConsole,那么此时在Debug编译模式下

    $(SolutionDir)的值为D:\LzrabbitRabbit

    $(ProjectDir)的值为D:\LzrabbitRabbit\TestConsole

    $(TargetPath)值为D:\LzrabbitRabbit\TestConsole\bin\Debug\TestConsole.exe

    $(TargetDir)值为D:\LzrabbitRabbit\TestConsole\bin\Debug\

    举个例子:比如我们在D盘根目录建立了一个控制台项目TestConsole,解决方案目录为D:\LzrabbitRabbit,项目目录为

    D:\LzrabbitRabbit\TestConsole,那么此时在Debug编译模式下

    $(SolutionDir)的值为D:\LzrabbitRabbit

    $(ProjectDir)的值为D:\LzrabbitRabbit\TestConsole

    $(TargetPath)值为D:\LzrabbitRabbit\TestConsole\bin\Debug\TestConsole.exe

    $(TargetDir)值为D:\LzrabbitRabbit\TestConsole\bin\Debug\

T4 导入指令:

<#@ import namespace="namespace" #>

在 Visual Studio T4 文本模板的代码块中,import 指令允许您在不提供完全限定名称的情况下引用另一个命名空间中的元素。 它等效于 C# 中的 using 或 Visual Basic 中的 imports。默认已经导入了System命名空间的引用。

T4 包含指令:

<#@ include file="filePath" #>

  1. filePath 可以是绝对的,或相对于当前模板文件。

  2. filePath 可以包括用“%”分隔的环境变量。 例如:<#@ include file="%HOMEPATH%\MyIncludeFile.t4" #>
  3. 所包含的文件的名称不必使用扩展名“.tt”。可能需要针对包含的文件使用其他扩展名,例如,“.t4”。 这是因为,在您将 .tt 文件添加到项目中时,Visual Studio 会自动将其“自定义工具”属性设置为 TextTemplatingFileGenerator。 您通常不希望单独转换包含的文件。
  4. 在处理时,被包含内容就像是包含文本模板的组成部分一样。 不过,即使 include 指令后为普通文本块和标准控制块,也可以包括含有类功能块 <#+...#> 的文件。
  5. 包含指令可以提高代码复用率,比如我们可以将一些常用的程序集、命名空间引用放到一个文件里,使用时仅需要引用下即可,省去了每次都要重新引用一遍的烦恼,如我们建立Reference.ttinclude文件,里面包含了我们平时常用的程序集引用。
<#@ assembly name="System.Core.dll" #>

<#@ assembly name="System.Data.dll" #>

<#@ assembly name="System.Data.DataSetExtensions.dll" #>

<#@ assembly name="System.Xml.dll" #>

<#@ import namespace="System" #>

<#@ import namespace="System.Xml" #>

<#@ import namespace="System.Linq" #>

<#@ import namespace="System.Data" #>

<#@ import namespace="System.Data.SqlClient" #>

<#@ import namespace="System.Collections.Generic" #>

<#@ import namespace="System.IO" #>

使用时只需要使用包含指令引用下即可:

<#@ include file="$(ProjectDir)Reference.ttinclude"  #>

T4 CleanUpBehavior 指令:

<#@ CleanupBehavior processor="T4VSHost" CleanupAfterProcessingtemplate="true" #>

T4 自定义指令:

请参见创建自定义 T4 文本模板指令处理器

文本块:

文本块是直接复制到输出的内容。 文本块没有特殊格式。 例如,下面的文本模板将生成一个包含单词“Hello World!”的文本文件:

<#@output extension=".txt" #>

Hello World! 

控制块:

控制块是用于转换模板的程序代码节。 默认语言是 C#,但若要使用 Visual Basic,可以在文件开头编写以下指令:

<#@ template language="VB" #>

用于编写控制块代码的语言与生成的文本的语言无关。

标准控制块:

标准控制块是生成输出文件部件的程序代码节。

在模板文件中,可以混合使用任意数量的文本块和标准控制块。 但是,不能在控制块中嵌套控制块。 每个标准控制块都以 <# ... #> 符号分隔。

例如,如果使用下面的控制块和文本块,则输出文件包含行“0, 1, 2, 3, 4 Hello!”:

<#

    for(int i = 0; i < 4; i++)

    {

        Write(i + ", ");

    }

    Write("4");

#> Hello!

您可以交错文本和代码,而不必使用显式 Write() 语句。 以下示例输出“Hello!”四次: 

<#

    for(int i = 0; i < 4; i++)

    {

#>

Hello!

<#

    } 

#>

在代码中,可以使用 Write(); 语句的位置都可以插入文本块。

表达式控制块:

表达式控制块计算表达式并将其转换为字符串。 该字符串将插入到输出文件中。

表达式控制块以 <#= ... #> 符号分隔。

例如,如果使用下面的控制块,则输出文件包含“5”:

<#= 2 + 3 #> 

请注意,开始符号有三个字符“<#=”。

表达式可以包含作用域中的任何变量。 例如,下面的块输出数字行:

<#@ output extension=".txt" #>

<#

    for(int i = 0; i < 4; i++)

    {

#>

This is hello number <#= i+1 #>: Hello!

<#

    } 

#>

类功能控制块:

类功能控制块定义属性、方法或不应包含在主转换中的所有其他代码。 类功能块常用于编写帮助器函数。通常,类功能块位于单独的文件中,这样它们可以包含在多个文本模板中。

类功能控制块以 <#+ ... #> 符号分隔。

例如,下面的模板文件声明并使用一个方法:

<#@ output extension=".txt" #>

Squares:

<#

    for(int i = 0; i < 4; i++)

    {

#>

    The square of <#= i #> is <#= Square(i+1) #>.

<#

    } 

#>

That is the end of the list.

<#+   // Start of class feature block

private int Square(int i)

{

    return i*i;

}

#>

类功能必须编写在文件末尾。 不过,即使 include 指令后跟标准块和文本,也可以 <#@include#> 包含类功能的文件。

另外,类功能块也可以包含文本块。
可以编写生成文本的方法。 例如

List of Squares:

<#

   for(int i = 0; i < 4; i++)

   {  WriteSquareLine(i); }

#>

End of list.

<#+   // Class feature block

private void WriteSquareLine(int i)

{

#>

   The square of <#= i #> is <#= i*i #>.

<#   

}

#>

将文本生成方法放置在可供多个模板包含的单独文件中,是非常有用的。


T4文本模板编写是T4模板运用的基础,掌握了这些简单的编写规则,再结合上节T4文本模板转换过程中的示例,我们就可以动手编写基于T4模板的代码生成器了。

详见下节:一个简单的代码生成器(T4文本模板运用)

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

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

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

  2. T4 文本模板编写准则

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

  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. 牛客网-《剑指offer》-从尾到头打印链表

    题目:http://www.nowcoder.com/practice/d0267f7f55b3412ba93bd35cfa8e8035 C++ /** * struct ListNode { * i ...

  2. NGINX源代码自我总结(一)

    查看源代码入门 这是一篇关于NGINX的MAIN()函数入门说明文章,相比其他这篇十分枯燥,其实写的时候更是无聊,不过学了这么长时间的WEB开发,连NGINX源代码都没有读下来,总是觉得有些缺憾,希望 ...

  3. vim自动保存折叠

    我经常使用的是手工折叠方式,就是 :set foldmethod=manual vim常用的折叠命令有: zf:折叠选定的行 zo:打开折叠 zR:打开所有折叠 zM:关闭所有折叠 zd:删除折叠 我 ...

  4. ETL面试题

    1. What is a logical data mapping and what does it mean to the ETL team? 什么是逻辑数据映射?它对ETL项目组的作用是什么? 答 ...

  5. python之函数用法fromkeys()

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #python之函数用法fromkeys() #fromkeys() #说明:用于创建一个新字典,以序列seq ...

  6. Web工程中各类地址的写法

    1)总体原则 在java web开发中,只要是url地址,那么最好以“/”开头,也就是绝对路径的方式.那么这个“/”到底代表什么呢? 如果“/”是给服务器用的,则代表当前web工程:如果是给浏览器用的 ...

  7. 设置char变量指定位为0或1

    int GetBit(char c,int i)//取c的第i位 { ; } void SetBit(char & c,int i, int v)//设置c的第i位为v,v是0或1 { if( ...

  8. 在大负载中使用LoadRunner进行负载测试()

    在大负载中使用LoadRunner进行负载测试,需要配置一些环境来满足大负载下各种资源的充足: 1.为了避免出现“No Buffer Space Available”的错误,需要进行如下配置: 1)修 ...

  9. Docker安装和常用命令

    Docker安装 Docker的安装可以参考 https://docs.docker.com/ 下面的 Get Docker / Docker CE / Linux, 需要关注的主要是CentOS和U ...

  10. ubuntu 14.04 lts安装教程:u盘安装ubuntu 14.04 lts步骤

    绿茶小编带来了ubuntu 14.04 lts安装教程,下文详细讲解了u盘安装ubuntu 14.04 lts的步骤,很简单,只需要一个工具就能够轻松使用u盘安装ubuntukylin 14.04系统 ...