T4模版引擎之基础入门
额,T4好陌生的名字,和NuGet一样很悲催,不为世人所熟知,却又在背后默默无闻的奉献着,直到现在我们项目组的人除了我之外,其它人还是对其豪无兴趣,基本上是连看一眼都懒得看,可怜的娃啊。。。
T4(Text Template Transformation Toolkit)是微软官方在VisualStudio 2008中开始使用的代码生成引擎。在 Visual Studio 中,“T4 文本模板”是由一些文本块和控制逻辑组成的混合模板,它可以生成文本文件。 在 Visual C# 或 Visual Basic 中,控制逻辑编写为程序代码的片段。生成的文件可以是任何类型的文本,例如网页、资源文件或任何语言的程序源代码。现在的VS中只要与代码生成相关的场景基本上都能找T4的身影,比如MVC的视图模板,Entity Framwork的DataContext模板等等。
在学习枯燥的概念前我们先来看一下用T4模版快速生成POCO实体类的示例
打开VS2010建一个项目,然后右击项目文件选择新建项,在文件列表中找到文件模版,如图所示
修改TextTemplate1.tt文件内容如下

- <#@ template debug="false" hostspecific="false" language="C#" #>
- <#@ output extension=".cs" #>
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace ConsoleApplication1
- {
- public class User
- {
- /// <summary>
- /// 用户ID
- /// </summary>
- public int UserID { get; set; }
- /// <summary>
- /// 用户名
- /// </summary>
- public string UserName { get; set; }
- /// <summary>
- /// 密码
- /// </summary>
- public string Password { get; set; }
- /// <summary>
- /// </summary>
- public string Email { get; set; }
- /// <summary>
- /// 手机号
- /// </summary>
- public string Mobile { get; set; }
- }
- }

点击Ctrl+S然后可以看到自动生成了一个TextTemplate1.cs文件

- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace ConsoleApplication1
- { public class User
- {
- /// <summary>
- /// 用户ID
- /// </summary>
- public int UserID { get; set; }
- /// <summary>
- /// 用户名
- /// </summary>
- public string UserName { get; set; }
- /// <summary>
- /// 密码
- /// </summary>
- public string Password { get; set; }
- /// <summary>
- /// </summary>
- public string Email { get; set; }
- /// <summary>
- /// 手机号
- /// </summary>
- public string Mobile { get; set; }
- }
- }

是不是很神奇,T4模版引擎会根据你在模版里定义的内容自动生成相应的文件,当然本示例过于简单,完全不能展现T4的强大,当你若真正了解T4后,会发现神马代码生成器全都是浮云,T4才是王道,利用T4你完全可以轻松生成属于自己风格的任何类型代码,在下篇文章会有实例展示如何通过T4连接数据库自动生成POCO类,基本上这个才是我们用T4的最大意图,呵呵,在这之前还是老老实实看看枯燥乏味的T4基础知识吧。
T4 文本模板有两种类型:设计时 T4 文本模板和运行时 T4 文本模板(“预处理过的”模板)
- 设计时模版
可在应用程序中执行运行时 T4 文本模板(“预处理过的”模板)以便生成文本字符串(通常作为其输出的一部分)。
Preprocessed text template file to your project.'> 若要创建运行时模板,请向您的项目中添加“已预处理的文本模板”文件。 Custom Tool property to TextTemplatingFilePreprocessor.'>另外,您还可以添加纯文本文件并将其“自定义工具”属性设置为“TextTemplatingFilePreprocessor”。
Run-Time Text Generation by using Preprocessed T4 Text Templates.'> 有关更多信息,请参见使用预处理 T4 文本模板生成运行时文本。 Writing a T4 Text Template.'>有关模板语法的更多信息,请参见编写 T4 文本模板。
- 运行时模版
在 Visual Studio 中执行设计时 T4 文本模板,以便定义应用程序的部分源代码和其他资源。
.cs, .vb, or other source files.'> 通常,您可以使用读取单个输入文件或数据库中的数据的多个模板,并生成一些 .cs、.vb 或其他源文件。 每个模板都生成一个文件。 在 Visual Studio 或 MSBuild 内执行它们。
Writing a T4 Text Template.'>Text Template file to your project.'> 若要创建设计时模板,请向您的项目中添加“文本模板”文件。 Custom Tool property to TextTemplatingFileGenerator.'>另外,您还可以添加纯文本文件并将其“自定义工具”属性设置为“TextTemplatingFileGenerator”。
Design-Time Code Generation by using T4 Text Templates.'>有关更多信息,请参见使用 T4 文本模板生成设计时代码。 Writing a T4 Text Template.'>有关模板语法的更多信息,请参见编写 T4 文本模板。
文本模板由以下部件组成:
Directives - elements that control how the template is processed.'>指令 - 控制模板处理方式的元素。
Text blocks - content that is copied directly to the output.'>文本块 - 直接复制到输出的内容。
Control blocks - program code that inserts variable values into the text, and controls conditional or repeated parts of the text.'>控制块 - 向文本插入可变值并控制文本的条件或重复部件的程序代码。
T4 文本模板指令
- T4模版指令
- <#@ template [language="C#"] [compilerOptions="options"] [culture="code"] [debug="true"] [hostspecific="true"] [inherits="templateBaseClass"] #>
- 模版指令中所有特性均为可选的
- langeuage:输出语言,有效值C#、VB,默认为C#
- debug:是否启用调试,有效值true、false,默认为false。特别说明下这个调试真的不咋地,很容易让VS崩溃,很鸡肋的功能,
- hostspecific:有效值true、false,默认为false。true, a property named Host is added to the class generated by your text template.'>如果将此特性的值设置为 true,则会将名为 Host 的属性添加到由文本模板生成的类中。 Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost.'>该属性是对转换引擎的宿主的引用,并声明为Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost。
- Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost.'>Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost.'>inherits:可以指定模板的程序代码可以继承自另一个类,这个类也可以从文本模板生成。目前木有使用过,基本上可以忽略
- Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost.'>compilerOptions:有效值为任何有效的编译器选项。基本上可以忽略
- T4 参数指令
- <#@ parameter type="Full.TypeName" name="ParameterName" #>
顾名思义,就是用来传参的,应该是用在运行时模版的(预处理模版)
- T4 输出指令
- <#@ output extension=".fileNameExtension" [encoding="encoding"] #>
比较重要的指令,用于设置输出文件的后缀名和文件编码
extension:输出文件扩展名,默认为".cs"
encoding:文件编码,默值为utf-8(这里不能确定,我测试是utf-8)
- T4 程序集指令
- <#@ assembly name="[assembly strong name|assembly file name]" #>
- 程序集指令相当于VS里面我们添加程序集引用的功能,该指令只有一个参数name,用以指定程序集名称,如果程序集已经在GAC里面注册,那么只需要写上程序集名称即可,如<#@ assembly name="System.Data.dll" #>,否则需要指定程序集的物理路径。
- T4模版的程序集引用是完全独立的,也就是说我们在项目中引用了一些程序集,然后项目中添加了一个T4模版,T4模版所需要的所有程序集引用必须明确的在模版中使用程序集执行引用才可以。
- T4模版自动加载以下程序集Microsoft.VisualStudio.TextTemplating.1*.dll、System.dll、WindowsBase.dll,如果用到了其它的程序集需要显示的使用程序集添加引用才可以
- 可以使用 $(variableName) 语法引用 Visual Studio 或 MSBuild 变量(如 $(SolutionDir)),以及使用 %VariableName% 来引用环境变量。介绍几个常用的$(variableName) 变量:
$(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\
- T4 导入指令
- <#@ import namespace="namespace" #>
在 Visual Studio T4 文本模板的代码块中,import 指令允许您在不提供完全限定名称的情况下引用另一个命名空间中的元素。 它等效于 C# 中的 using 或 Visual Basic 中的 imports。默认已经导入了System命名空间的引用。
- T4 包含指令
- <#@ include file="filePath" #>
- filePath 可以是绝对的,或相对于当前模板文件。
- filePath 可以包括用“%”分隔的环境变量。 例如:<#@ include file="%HOMEPATH%\MyIncludeFile.t4" #>
- 所包含的文件的名称不必使用扩展名“.tt”。可能需要针对包含的文件使用其他扩展名,例如,“.t4”。 这是因为,在您将 .tt 文件添加到项目中时,Visual Studio 会自动将其“自定义工具”属性设置为 TextTemplatingFileGenerator。 您通常不希望单独转换包含的文件。
- 在处理时,被包含内容就像是包含文本模板的组成部分一样。 不过,即使 include 指令后为普通文本块和标准控制块,也可以包括含有类功能块 <#+...#> 的文件。
- 包含指令可以提高代码复用率,比如我们可以将一些常用的程序集、命名空间引用放到一个文件里,使用时仅需要引用下即可,省去了每次都要重新引用一遍的烦恼,如我们建立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" #>
- <#@ assembly name="System.Core.dll" #>
文本块
文本块直接向输出文件插入文本。 文本块没有特殊格式。 例如,下面的文本模板将生成一个包含单词“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 #>.
- <#
- }
- #>

将文本生成方法放置在可供多个模板包含的单独文件中,是非常有用的。
嗯,大概的基础点应该就这些了,更多的自己去MSDNhttp://msdn.microsoft.com/zh-cn/library/bb126445详细了解吧
这里解释点容易让人困惑的地方,我们在T4模版里面引用的程序集和那些命名空间都是利用T4生成代码需要使用的,也就是T4模版要用的,和我们要生成的目标类毛关系都没有,当初为搞清楚这点可是费了不精力。T4初看起来很复杂,其实稍微花些心思研究下,主要似乎把MSDN看懂还是很容易学会的,一旦掌握了受用无穷
T4模版引擎之基础入门的更多相关文章
- T4教程1 T4模版引擎之基础入门
T4模版引擎之基础入门 额,T4好陌生的名字,和NuGet一样很悲催,不为世人所熟知,却又在背后默默无闻的奉献着,直到现在我们项目组的人除了我之外,其它人还是对其豪无兴趣,基本上是连看一眼都懒得看 ...
- 黄聪:VS2010开发T4模版引擎之基础入门
原文:http://www.cnblogs.com/lzrabbit/archive/2012/07/15/2591085.html 额,T4好陌生的名字,和NuGet一样很悲催,不为世人所熟知,却又 ...
- T4((Text Template Transformation Toolkit))模版引擎之基础入门 C#中文本模板(.tt)的应用
1 关于C#中文本模板(.tt)的简单应用https://blog.csdn.net/zunguitiancheng/article/details/78011145 任何一个傻瓜都能写出计算机能理解 ...
- T4教程2 T4模版引擎之生成数据库实体类
T4模版引擎之生成数据库实体类 在通过T4模版引擎之基础入门 对T4有了初步印象后,我们开始实战篇.T4模板引擎可以当做一个代码生成器,代码生成器的职责当然是用来生成代码(这不是废话吗).而这其中 ...
- [转]T4模版引擎之生成数据库实体类
本文转自:http://www.cnblogs.com/lzrabbit/archive/2012/07/18/2597953.html 在通过T4模版引擎之基础入门 对T4有了初步印象后,我们开始实 ...
- T4模版引擎之生成数据库实体类
在通过T4模版引擎之基础入门 对T4有了初步印象后,我们开始实战篇.T4模板引擎可以当做一个代码生成器,代码生成器的职责当然是用来生成代码(这不是废话吗).而这其中我们使用的最普遍的是根据数据库生成实 ...
- C# t4模版引擎笔记 引入外部dll
<#@ assembly name="D:\Documents\Downloads\Util\Util\bin\Debug\Util.dll" #> <#@ im ...
- T4模版基础例子
<#@ template debug="false" hostspecific="true" language="C#" #> ...
- Nodejs学习笔记(五)--- Express安装入门与模版引擎ejs
目录 前言 Express简介和安装 运行第一个基于express框架的Web 模版引擎 ejs express项目结构 express项目分析 app.set(name,value) app.use ...
随机推荐
- Unity3D方法来隐藏和显示对象
Unity3D作 在使用unity3d开发游戏的过程中.我们经常会遇到须要隐藏或者显示的操作,针对这一点,以下做了一些总结. 一.设置Renderer状态 在游戏的开发中,全部可以被渲染的物体都包括有 ...
- AndroidUI的组成部分ProgressBar
package com.gc.progressbar; /* * 1.ProgressBar组件也是一组重要的组件,ProgressBar本身代表了进度条组件, * 它还派生了两个经常使用的组件:Se ...
- 非常棒的Visual Studo调试插件:OzCode 2.0 下载地址
最新版下载地址 http://download.csdn.net/detail/simadi/8925511 如果你是一名C#开发者,那么,你则需要OzCode.它将可视化调试的概念上升到了一个新的高 ...
- 探索C/C++大数快(自然数)模板
本文fcbruce个人原创整理.转载请注明出处http://blog.csdn.net/u012965890/article/details/40432511,谢谢. 我们知道在C/C++中int型可 ...
- 安卓培训第五天---上传文件SD卡
有关如何将文件上传到先说说SD卡: package com.example.lesson05_02; import java.io.File; import java.io.FileNotFoundE ...
- Android client和服务器JSP互传中国
出于兼容性简化.传统中国等多国语言.推荐使用UTF-8编码. 首选.我们期待Android到底应该怎么办: 在发送前,应该对參数值要进行UTF-8编码,我写了一个static的 转换函数.在做发送动作 ...
- dapper支持oracle游标
dapper支持oracle游标 Dapper是一个轻型的ORM类.它有啥优点.缺点相信很多朋友都知道了,园里也有很多朋友都有相关介绍,这里就不多废话. 如果玩过Oracle都知道,存储过程基本都是通 ...
- [Python 学习] 两、在Linux使用平台Python
在本节,它介绍了Linux如何使用平台Python 1. Python安装. 今天,大多数把自己的版本号Python的,它不能被安装.假设你要安装它,可以使用相应的安装指令. Fedora:先以roo ...
- Android MotionEvent事故响应机制
于android于.主要活动包括点击.按.拖累.滑动等操作,这些构成了Android事件响应,总体而言,,所有事件由例如以下三部分构成的基础: 按(action_down),搬家(action_mov ...
- html不常见问题汇总
写html已经好长一段时间了,也遇到了不少问题,跟大家分享下 form是不可以嵌套的 说明:如果嵌套会有很多问题 但是可以并列 <html> <head> </head& ...