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

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. LintCode: Identical Binary Tree

    C++ /** * Definition of TreeNode: * class TreeNode { * public: * int val; * TreeNode *left, *right; ...

  2. C++ 第十课:标准c时间与日期函数

    asctime() 时间文本格式 clock() 返回自程序开始运行所经过的时间 ctime() 返回特定格式时间 difftime() 两时刻的间隔 gmtime() 返回指向当前格林威治时间的指针 ...

  3. spring boot 运行提示:Process finished with exit code 1

    spring boot 运行提示:Process finished with exit code 1 经检查发现是由于在application.properties配置文件中将某些自定义配置项移除了, ...

  4. Jaspersoft Studio 导出PDF格式中文不显示

    1:设置字体 2:应用上面设置的字体

  5. 动态加载jar包(一)

    一.编写被调用的类 package com.qunar.helloworld; public class HelloWorld { public String sayHello(){ return ( ...

  6. Java 基础【15】 压缩与解压缩

    Java.util.zip 提供用于读写标准 ZIP 和 GZIP 文件格式的类. 还包括使用 DEFLATE 压缩算法(用于 ZIP 和 GZIP 文件格式)对数据进行压缩和解压缩的类. 依赖 Jd ...

  7. 基于内容的推荐 java实现

    这是本人在cousera上学习机器学习的笔记,不能保证其正确性,慎重參考 看完这一课后Content Based Recommendations 后自己用java实现了一下 1.下图是待处理的数据,代 ...

  8. matplotlib01

    matplotlib是基于numpy的一套Python工具包.这个包提供了丰富的数据绘图工具,可实现数据分析的可视化. 所以在安装matplotlib时,需要先安装numpy包.

  9. 1768:最大子矩阵(NOIP2014初赛最后一题)

    1768:最大子矩阵 总时间限制: 1000ms 内存限制: 65536kB 描述 已知矩阵的大小定义为矩阵中所有元素的和.给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵. 比如 ...

  10. UVM:8.4.3 用factory 机制创建实例的接口

    1.create_object_by_name,依据类名字创建object,原型: 一般仅仅用第一个: 2.create_object_by_type.依据类型创建一个object,原型: 一般仅仅用 ...