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

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》-包含min函数的栈

    题目:http://www.nowcoder.com/practice/4c776177d2c04c2494f2555c9fcc1e49 辅助栈 C++ class Solution { public ...

  2. vSphere Data Protection – a new backup product included with vSphere 5.1

    August 27, 2012 By Vladan SEGET This new backup product replaces VMware Data Recovery, which has bee ...

  3. VMware Lab setup - A virtualized lab for testing HA and DRS

    https://www.simple-talk.com/sysadmin/virtualization/vmware-lab-setup---a-virtualized-lab-for-testing ...

  4. Mysql prepare 语法

    最近一直使用语句,SELECT auction_id, auction_name,SUM(new_cart),SUM(new_collect),SUM(total_cart),SUM(total_co ...

  5. Iterator接口用法

    1.所有实现Collection接口的容器类都有一个iteractor方法,用于返回一个实现了Iteractor接口的对象, 2.Iteractor对象成为迭代器,用以实现对容器内元素的遍历操作 3. ...

  6. MongoDB numa系列问题一:[initandlisten] connection refused because too many open connections:

    1:Mongod日志有很多这样的报错: [initandlisten] connection refused because too many open connections: 2:查看系统的限制 ...

  7. Python实现微信刷卡支付(条码支付)MicroPay

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/7686765.html 一:资料阅读 场景介绍:https://pay.weixin.qq.com/wiki/d ...

  8. IOS-异常处理

    http://blog.csdn.net/ndscoahz/article/details/50866229 http://www.cnblogs.com/snail-007/p/4564422.ht ...

  9. shell脚本read -t 超时输入测试

    [root@server0 shellStudy]# cat timeout.sh #!/bin/bash TIMEOUT=3 #超时间隔 echo "What is your name?& ...

  10. Linux环境变量加载顺序

    01.环境变量文件描述 /etc/profile: 此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行,并从/etc/profile.d目录的配置文件中搜集shell的设置./etc ...