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

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. Word 之 清除页眉下划线

    在应用 Word 的时候,有时我们需要为文件添加页眉,但是首页却不需要.这时一般都会勾选“ 首页不同 ”并关闭页眉页脚.一种情况页眉不显示任何信息及下划线,另一种情况页眉留有下划线.以下针对第二种情况 ...

  2. PageObject&PageFactory

    几篇介绍PageObject&PageFactory文章: PageFactory: http://code.google.com/p/selenium/wiki/PageFactory Pa ...

  3. JAVA设计模式——第 2 章 代理模式【Proxy Pattern】(转)

    什么是代理模式呢?我很忙,忙的没空理你,那你要找我呢就先找我的代理人吧,那代理人总要知道被代理人能做哪些事情不能做哪些事情吧,那就是两个人具备同一个接口,代理人虽然不能干活,但是被代理的人能干活呀. ...

  4. 安装 LUA

    为了以后方便,记录一下步骤 1.yum install readline-devel 2.wget http://www.lua.org/ftp/lua-5.1.4.tar.gz 3.cd lua-5 ...

  5. SpringBoot使用Mybatis注解进行一对多和多对多查询(2)

    SpringBoot使用Mybatis注解进行一对多和多对多查询 GitHub的完整示例项目地址kingboy-springboot-data 一.模拟的业务查询 系统中的用户user都有唯一对应的地 ...

  6. iOSUIWebView---快停下啦,你的愚蠢的行为

    公元前 之前还是学生时代的时候给社团们学弟学妹们介绍iOS编程的时候,简单的准备了图灵ios培训第一周(使用UIWebView创建简易浏览器), NSURL *url =[NSURL URLWithS ...

  7. docker 实战---多台物理主机的联网,容器桥接到物理网络拓扑图(四)

    非常多朋友说上一篇中对网络的描写叙述不够清楚,感谢热心的群友彩笔程序猿: 提供了他理解的图,在这里贴一下: 我自己也补画了一副多台机器互联的图,欢迎大家留言讨论: 主机A和主机B的网卡一都连着物理交换 ...

  8. SElinux测试及排错

    一.修改SElinux的状态 #sestatus --查看状态 #setenforce --临时修改 #setenforce #getenforce #vim /etc/selinux/config ...

  9. C++中public、protected及private使用方法

    1.类的一个特征就是封装,public和private作用就是实现这一目的.所以: 用户代码(类外)能够訪问public成员而不能訪问private成员:private成员仅仅能由类成员(类内)和友元 ...

  10. Jqeury Mobile实战之切屏效果以及屏幕滚动到底端加载更多和点击切换更多

    http://blog.csdn.net/q718330882/article/details/46120691 //页面滚动到底部加载更多事件 $( window ).scroll(function ...