一、T4簡介
T4(Text Template Transformation Toolkit)在 Visual Studio 中,“T4 文本模板”是由一些文本塊和控制邏輯組成的混合模板,它可以生成文本文件。 在 Visual C# 或 Visual Basic 中,控制邏輯編寫為程序代碼的片段。生成的文件可以是任何類型的文本,例如網頁、資源文件或任何語言的程序源代碼。
T4 文本模板有兩種類型:
若要創建運行時模板,請向您的項目中添加“已預處理的文本模板”文件。
另外,您還可以添加純文本文件並將其“自定義工具”屬性設置為“TextTemplatingFilePreprocessor”。
2、設計時模板
在 Visual Studio 中執行設計時 T4 文本模板,以便定義應用程序的部分源代碼和其他資源。
通常,您可以使用讀取單個輸入文件或數據庫中的數據的多個模板,並生成一些 .cs、.vb 或其他源文件。
每個模板都生成一個文件。 在 Visual Studio 或 MSBuild 內執行它們。
若要創建設計時模板,請向您的項目中添加“文本模板”文件。 另外,您還可以添加純文本文件並將其“自定義工具”屬性設置為“TextTemplatingFileGenerator”。
二、T4例子--HelloWorld
最簡單的HelloWorld,通過此例子,可以看到T4的基本結構
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Collections.Generic" #>
using System;
namespace Test
{
public class HelloWorld
{
public static void Main(string[] args)
{
<#
List<Person> people = GetPersonList();
foreach(Person p in people)
{
#>
Console.WriteLine("Hello {0},Welcome to T4 World!","<#= p.Name #>");
<#}
#>
}
}
}
<#+
//類
public class Person
{
///名稱
public string Name{ get; set; }
public Person(string name)
{
this.Name = name;
}
}
//初始化眾人
public List<Person> GetPersonList()
{
List<Person> people = new List<Person>();
Person p1 = new Person("Tom");
Person p2 = new Person("Jim");
Person p3 = new Person("Lucy");
people.Add(p1);
people.Add(p2);
people.Add(p3);
return people;
}
#>
生成的代碼:
using System;
namespace Test
{
public class HelloWorld
{
public static void Main(string[] args)
{
Console.WriteLine("Hello {0},Welcome to T4 World!", "Tom");
Console.WriteLine("Hello {0},Welcome to T4 World!", "Jim");
Console.WriteLine("Hello {0},Welcome to T4 World!", "Lucy");
}
}
}
三、T4模板的基本結構
代碼塊的總體分類,就是兩種:文本、程序腳本。
我感覺這樣分類就夠了,跟我們用c#寫代碼生成原理差不多。也是又C#代碼和文本組成的。
文本:就是需要生成的文本
程序腳本:內部執行,最終生成想要的文本。T4中<# #>中的部分都屬於程序腳本內容。
為了細分語法,方便大家更好的理解,用“塊”(Block)來表示構成T4模板的基本單元,它們基本上可以分成5類:指令塊(Directive Block)、文本塊(Text Block)、代碼語句塊(Statement Block)、表達式塊(Expression Block)和類特性塊(Class Feature Block)。
1、指令塊(Directive Block)
和ASP.NET頁面的指令一樣,它們出現在文件頭,通過<#@…#>表示。其中<#@ template …#>指令是必須的,用於定義模板的基本屬性,比如編程語言、基於的文化、是否支持調式等等。比較常用的指令還包括用於程序集引用的<#@ assembly…#>,用於導入命名空間的<#@ import…#>等等。
指令通常是模板文件或包含的文件中的第一個元素。不應將它們放置在代碼塊 <#...#> 內,也不應放置在類功能塊 <#+...#> 之后。
T4 模板指令
<#@ template [language="VB"] [hostspecific="true"] [debug="true"] [inherits="templateBaseClass"] [culture="code"] [compilerOptions="options"] #>
T4 參數指令
<#@ parameter type="Full.TypeName"name="ParameterName"#>
T4 輸出指令
<#@ output extension=".fileNameExtension"[encoding="encoding"] #>
T4 程序集指令
<#@ assembly name="[assembly strong name|assembly file name]"#>
T4 導入指令
<#@ import namespace="namespace"#>
T4 包含指令
<#@ include file="filePath"#>
2、文本塊(Text Block)
文本塊就是直接原樣輸出的靜態文本,不需要添加任何的標簽。
3、代碼語句塊(Statement Block)
代碼語句塊通過<#Statement#>的形式表示,中間是一段通過相應編程語言編寫的程序調用,我們可以通過代碼語句快控制文本轉化的流程。在上面的代碼中,我們通過代碼語句塊實現對一個數組進行遍歷,輸出重復的Console.WriteLine("Hello {0},Welcome to T4 World!","<#= p.Name #>");語句。
4、表達式塊(Expression Block)
表達式塊以<#=Expression#>的形式表示,通過它之際上動態的解析的字符串表達內嵌到輸出的文本中。比如在上面的foreach循環中,每次迭代輸出的人名就是通過表達式塊的形式定義的(<#= p.Name #>)
5、類特性塊(Class Feature Block)
如果文本轉化需要一些比較復雜的邏輯,我們需要寫在一個單獨的輔助方法中,甚至是定義一些單獨的類,我們就是將它們定義在類特性塊中。類特性塊的表現形式為<#+ FeatureCode #>,對於Hello World模板,得到人名列表的GetPersonList方法就定義在類特性塊中。