T4 模板
T4 文本模板有两种类型:设计时 T4 文本模板和运行时 T4 文本模板(预处理过的文本模板)
看到了木有,第一个“预处理的文本模板”和第二个是文本模板。
设计时的模板:在设计时显示的结果的一种模式.也就是所见所得的一种模式吧,文本模板里属性的“自定义工具”是:TextTemplatingFileGenerator,可以使用Ctrl+S查看;
运行时的模板:可以在运行时在应用程序中生成文本字符串。 文本模板里属性的“自定义工具”是:TextTemplatingFilePreprocessor,不可以使用Ctrl+S查看;
文本模板由以下部件组成:
-
指令 - 控制模板处理方式的元素。
-
文本块 - 直接复制到输出的内容。
-
控制块 - 向文本插入可变值并控制文本的条件或重复部件的程序代码。
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,则会将名为 Host 的属性添加到由文本模板生成的类中。 该属性是对转换引擎的宿主的引用,并声明为Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost。
-
inherits:可以指定模板的程序代码可以继承自另一个类,这个类也可以从文本模板生成。目前木有使用过,基本上可以忽略。
-
compilerOptions:有效值为任何有效的编译器选项。基本上可以忽略。
T4 参数指令:
<#@ parameter type="Full.TypeName" name="ParameterName" #>
顾名思义,就是用来传参的,应该是用在运行时模版的(预处理模版)
T4 输出指令:
<#@ output extension=".fileNameExtension" [encoding="encoding"] #>
比较重要的指令,用于设置输出文件的后缀名和文件编码
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目录(取决于当前的编译模式)
string solutionsPath = Host.ResolveAssemblyReference("$(SolutionDir)");//解决路径
string projectPath = Host.ResolveAssemblyReference("$(ProjectDir)");//项目路径
string a = Path.GetDirectoryName(Host.TemplateFile); //项目路径
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" #>
文本块
文本块直接向输出文件插入文本。 文本块没有特殊格式。 例如,下面的文本模板将生成一个包含单词“Hello World!”的文本文件:
<#@ output extension=".txt" #> Hello World!
控制块
标准控制块
标准控制块是生成输出文件部件的程序代码节。
在模板文件中,可以混合使用任意数量的文本块和标准控制块。 但是,不能在控制块中嵌套控制块。 每个标准控制块都以 <# ... #> 符号分隔。
例如,如果使用下面的控制块和文本块,则输出文件包含行“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! <# } #>
表达式控制块
表达式控制块计算表达式并将其转换为字符串。 该字符串将插入到输出文件中。
表达式控制块以 <#= ... #> 符号分隔。
请注意,开始符号有三个字符“<#=”。
表达式可以包含作用域中的任何变量。 例如,下面的块输出数字行:
<#@ 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#> 包含类功能的文件。
类功能块可以包含文本块
可以编写生成文本的方法。 例如:
<# 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里是没有像VS的C#调试那么简单,在左边设置一个调试点,然后点击运行就OK了。
不过,也差不多吧!值需要的只是:<# Debugger.Break(); #> 把这个放到你需要调试的地方,等你运行的时候,就会自动的跳到这里啦。然后,你就可以看到你的内容,比如我在我的项目中调试中的结果: