一、什么是T4?
1.1、T4简介
T4,即4个T开头的英文字母组合:Text Template Transformation Toolkit,是微软官方在Visual Studio 2008开始使用的代码生成引擎。T4是由一些文本块和控制逻辑组成的混合模板,简单地说,T4可以根据模板生成您想要的文件,如类文件、文本文件、HTML等等。
VS提供了一套基于T4引擎的代码生成执行环境,由以下程序集构成:
Microsoft.VisualStudio.TextTemplating.10.0.dll
Microsoft.VisualStudio.TextTemplating.Interfaces.10.0.dll
Microsoft.VisualStudio.TextTemplating.Modeling.10.0.dll
Microsoft.VisualStudio.TextTemplating.VSHost.10.0.dll
1.2、T4模板类型
T4模板有两种类型:
1)运行时模板
在应用程序中执行运行时T4文本模板,以便生成文本字符串。
2)设计时模板
设计时T4文本模板,以便定义应用程序的部分源代码和其它资源。
插件安装
VS默认的编辑工具无高亮、无提示,错误不容易定位,建议安装tangible T4 Editor插件进行编写T4代码。
二、T4 Hello World示例
假设有一个控制台应用程序LinkTo.Test.ConsoleT4,现在要输出"Hello World"字符串,Program代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace LinkTo.Test.ConsoleT4 { class Program { static void Main(string[] args) { Console.WriteLine("Hello World"); Console.Read(); } } }
现在把Program.cs文件删除掉,利用T4模板生成一个与上述代码相同的Program.cs,操作方法如下:
1)项目右键"添加"->"新建项"->"文本模板",将名称更改为Program.tt。
2)Program.tt的代码如下:
<#@ output extension=".cs" #> using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; <# string ClassName = "Program"; #> namespace LinkTo.Test.ConsoleT4 { class <#=ClassName #> { static void Main(string[] args) { Console.WriteLine("Hello World"); Console.Read(); } } }
3)点击保存,即可看到Program.tt下生成了一个Program.cs文件,代码与最初的Hello World一样。
三、T4 Hello World示例扩展
现在扩展一下Hello World示例,在程序中增加两个类:
1)Hello类,输出"Hello"。
2)World类,输出"World"。
代码如下:
<#@ template debug="false" hostspecific="false" language="C#" #> <#@ assembly name="System.Core" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ output extension=".cs" #> using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; <# string ClassName = "Program"; #> <# List<string> classNames = new List<string>() {"Hello","World"}; List<string> callMethods = new List<string>(); #> namespace LinkTo.Test.ConsoleT4 { <# foreach (string className in classNames) { callMethods.Add($"{className}.Show();"); #> class <#=className #> { /// <summary> /// <#=className #>类Show()方法 /// </summary> public static void Show() { Console.WriteLine("<#=className #>"); } } <# } #> class <#=ClassName #> { static void Main(string[] args) { Console.WriteLine("Hello World"); <# foreach (string callMethod in callMethods) { #> //<#=callMethod #>方法调用 <#=callMethod #> <# } #> Console.Read(); } } }