T4 模板 (Text Template Transformation Toolkit)

金珂
2023-12-01

    T4模板的定义非常简单,整个模板的内容包括两种形式:静态形式和动态动态。前者就是直接写在模板中作为原样输出的文本,后者是基于某种语言编写代 码,T4引擎会动态执行它们。这和我们通过内联的方式编写的ASP.NET页面很相似:HTML是静态的,以C#或者VB.NET代码便写的动态执行的代 码通过相应的标签内嵌其中。

现在我们直接通过VS来创建一个T4模板来生成我们期望的C#代码。右击项目文件,选择"Add"|"New Item",在模板列表中选择"Text Template"。指定文件名后确定,一个后缀名为.tt的文件会被创建,然后在该文件中编写如下的代码。

1: <#@ template debug="false" hostspecific="false" language="C#" #>
2: <#@ assembly name="System.Core.dll" #>
3: <#@ import namespace="System" #>
4: <#@ output extension=".cs" #>
5: using System;
6: 
7: namespace Artech.CodeGeneration
8: {
9: class Program
10: { 
11: staticvoid Main(string[] args)
12: { 
13: <# 
14: foreach(var person inthis.InitializePersonList()) 
15: {
16: #>Console.WriteLine("Hello, {0}","<#= person#>");
17: <# } #>
18: }
19: }
20: }
21: 
22: <#+
23: publicstring[] InitializePersonList()
24: {
25: returnnewstring[]{"Foo","Bar","Baz"};
26: }
27: #>
保存该文件后,一个.cs文件将会作为该TT文件的附属文件被添加。上述的这个TT文件虽然简单,却包含了构成一个T4模板的基本元素。在解读该T4模板之前,我们有必要先来了解一个完整的T4模板是如何构成的。


T4模板的基本结构:

它们基本上可以分成5类:指令块(Directive Block)、文本块(Text Block)、代码语句块(Statement Block)、表达式块(Expression Block)和类特性块(Class Feature Block)。

      1、指令块(Directive Block)

  和ASP.NET页面的指令一样,它们出现在文件头,通过<#@…#>表示。其中<#@ template …#>指令是必须的,用于定义模板的基本属性,比如编程语言、基于的文化、是否支持调式等等。比较常用的指令还包括用于程序集引用的<#@ assembly…#>,用于导入命名空间的<#@ import…#>等等。

  2、文本块(Text Block)

  文本块就是直接原样输出的静态文本,不需要添加任何的标签。在上面的模板文件中,处理定义在<#… #>、<#+… #>和<#=… #>中的文本都属于文本块。比如在指令块结束到第一个“<#”标签之间的内容就是一段静态的文本块。

1: using  System;  2:    3: namespace  Artech.CodeGeneration  4:  {  5: class  Program  6:  {  7: static void  Main( string [] args)  8:  {  9:

  3、代码语句块(Statement Block)

  代码语句块通过<#Statement#>的形式表示,中间是一段通过相应编程语言编写的程序调用,我们可以通过代码语句快控制文 本转化的流程。在上面的代码中,我们通过代码语句块实现对一个数组进行遍历,输出重复的Console.WriteLine(“Hello, {0}”, “Xxx”)语句。

1:  <#  2: foreach (var person  in this .InitializePersonList())  3:  {  4:  #>  5:  Console.Write( "Hello, {0}" , "<#= person#>" );  6:  <#  7:  }  8:  #>

  4、表达式块(Expression Block)

  表达式块以<#=Expression#>的形式表示,通过它之际上动态的解析的字符串表达内嵌到输出的文本中。比如在上面的foreach循环中,每次迭代输出的人名就是通过表达式块的形式定义的(<#=  person#>)

  5、类特性块(Class Feature Block)

  如果文本转化需要一些比较复杂的逻辑,我们需要写在一个单独的辅助方法中,甚至是定义一些单独的类,我们就是将它们定义在类特性块中。类特性块 的表现形式为<#+ FeatureCode #>,对于Hello World模板,得到人名列表的InitializePersonList方法就定义在类特性块中。


1:  <#+  2: public string [] InitializePersonList()  3:  {  4: return new string []{ "Foo" , "Bar" , "Baz" };  5:  }  6:  #>  


整个代码生成的输入,即XML文件Messages.xml和模板文件位于相同的目录下,但是我们需要通过Host属性的ResolvePath方法去解 析文件的物理路径。对ResolvePath方法的调用,需要模板<#@ template …#>指令中的hostspecific设置为true。

 

T4(Text Template Transformation Toolkit)则是微软官方在VisualStudio 2008中开始使用的代码生成引擎。 

1. T4 获取智能感知,安装  http://t4-editor.tangible-engineering.com/T4-Editor-Visual-T4-Editing.html  。。或者在vs2010中,插件管理中搜索

 

简单介绍一下T4模板语法

<#@ template language="C#v3.5" hostSpecific="true" debug="true" #>
这里可以指定模板使用的语言,hostSpecific="true"表示是否使用特定的host(Kalman Studio里面使用的是TableHost对象,必须实现接口ITextTemplatingEngineHost)

<#@ output extension=".cs" #>  指定生成文件的扩展名

<#@ assembly name="System.Data" #>
添加程序集引用,如果要使用第三方程序集,那么最好在项目中添加引用,或者加入到GAC

<#@ import namespace="System.Data" #>
导入要使用的命名空间,注意:这里的命名空间必须要在前面指定的程序集里面找得到的,比如我指定命名空间"System.Data","System.Data.Common",这些在程序集System.Data中都有的

<#@ include file="test.tt" #> 导入模板,类似Html的include用法


<#   #>  定义代码块

<#= #>  定义表达式

<#+ #>  定义变量



 类似资料: