C#T4模板

T4(Text Template Transformation Toolkit)是微软官方在VisualStudio 2008中开始使用的代码生成引擎。在 Visual Studio 中,“T4 文本模板”是由一些文本块和控制逻辑组成的混合模板,它可以生成文本文件。 在 Visual C# 或 Visual Basic 中,控制逻辑编写为程序代码的片段。生成的文件可以是任何类型的文本,例如网页、资源文件或任何语言的程序源代码。现在的VS中只要与代码生成相关的场景基本上都能找T4的身影,比如MVC的视图模板,Entity Framwork的DataContext模板等等。

 我们先来创建一个试试

 

T4 文本模板有两种类型

  • 设计时模版

  可在应用程序中执行运行时 T4 文本模板(“预处理过的”模板)以便生成文本字符串(通常作为其输出的一部分)。

  若要创建运行时模板,请向您的项目中添加“已预处理的文本模板”文件。 另外,您还可以添加纯文本文件并将其“自定义工具”属性设置为“TextTemplatingFilePreprocessor”。

  有关更多信息,请参见使用预处理 T4 文本模板生成运行时文本。 有关模板语法的更多信息,请参见编写 T4 文本模板

  • 运行时模版

  在 Visual Studio 中执行设计时 T4 文本模板,以便定义应用程序的部分源代码和其他资源。

  通常,您可以使用读取单个输入文件或数据库中的数据的多个模板,并生成一些 .cs、.vb 或其他源文件。 每个模板都生成一个文件。 在 Visual Studio 或 MSBuild 内执行它们。

  若要创建设计时模板,请向您的项目中添加“文本模板”文件。 另外,您还可以添加纯文本文件并将其“自定义工具”属性设置为“TextTemplatingFileGenerator”。

  有关更多信息,请参见使用 T4 文本模板生成设计时代码。 有关模板语法的更多信息,请参见编写 T4 文本模板。 

文本模板由以下部件组成:

指令 - 控制模板处理方式的元素。

文本块 - 直接复制到输出的内容。

控制块 - 向文本插入可变值并控制文本的条件或重复部件的程序代码。 

 

T4 文本模板指令

 

 

  • T4模版指令 
    <#@ template [language="C#"] [compilerOptions="options"] [culture="code"] [debug="true"] [hostspecific="true"] [inherits="templateBaseClass"] #>

     

  1. 模版指令中所有特性均为可选的
  2. langeuage:输出语言,有效值C#、VB,默认为C#
  3. debug:是否启用调试,有效值true、false,默认为false。特别说明下这个调试真的不咋地,很容易让VS崩溃,很鸡肋的功能,
  4. hostspecific:有效值true、false,默认为false。如果将此特性的值设置为 true,则会将名为 Host 的属性添加到由文本模板生成的类中。 该属性是对转换引擎的宿主的引用,并声明为Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost。
  5. inherits:可以指定模板的程序代码可以继承自另一个类,这个类也可以从文本模板生成。目前木有使用过,基本上可以忽略
  6. compilerOptions:有效值为任何有效的编译器选项。基本上可以忽略 
  • T4 参数指令
    <#@ parameter type="Full.TypeName" name="ParameterName" #>

     顾名思义,就是用来传参的,应该是用在运行时模版的(预处理模版)

  • T4 输出指令
    <#@ output extension=".fileNameExtension" [encoding="encoding"] #>

    比较重要的指令,用于设置输出文件的后缀名和文件编码
    extension:输出文件扩展名,默认为".cs"
    encoding:文件编码,默值为utf-8(这里不能确定,我测试是utf-8)

  1. 程序集指令相当于VS里面我们添加程序集引用的功能,该指令只有一个参数name,用以指定程序集名称,如果程序集已经在GAC里面注册,那么只需要写上程序集名称即可,如<#@ assembly name="System.Data.dll" #>,否则需要指定程序集的物理路径。
  2. T4模版的程序集引用是完全独立的,也就是说我们在项目中引用了一些程序集,然后项目中添加了一个T4模版,T4模版所需要的所有程序集引用必须明确的在模版中使用程序集执行引用才可以。
  3. T4模版自动加载以下程序集Microsoft.VisualStudio.TextTemplating.1*.dll、System.dll、WindowsBase.dll,如果用到了其它的程序集需要显示的使用程序集添加引用才可以
  4. 可以使用 $(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命名空间的引用。

  1. filePath 可以是绝对的,或相对于当前模板文件。
  2. filePath 可以包括用“%”分隔的环境变量。 例如:<#@ include file="%HOMEPATH%\MyIncludeFile.t4" #>
  3. 所包含的文件的名称不必使用扩展名“.tt”。可能需要针对包含的文件使用其他扩展名,例如,“.t4”。 这是因为,在您将 .tt 文件添加到项目中时,Visual Studio 会自动将其“自定义工具”属性设置为 TextTemplatingFileGenerator。 您通常不希望单独转换包含的文件。
  4. 在处理时,被包含内容就像是包含文本模板的组成部分一样。 不过,即使 include 指令后为普通文本块和标准控制块,也可以包括含有类功能块 <#+...#> 的文件。
  5. 包含指令可以提高代码复用率,比如我们可以将一些常用的程序集、命名空间引用放到一个文件里,使用时仅需要引用下即可,省去了每次都要重新引用一遍的烦恼,如我们建立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"  #>

     

 文本块

 文本块直接向输出文件插入文本。 文本块没有特殊格式。

<#@ 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(); 语句的位置都可以插入文本块。 

表达式控制块

表达式控制块计算表达式并将其转换为字符串。 该字符串将插入到输出文件中。
表达式控制块以 <#= ... #> 符号分隔。
例如,如果使用下面的控制块,则输出文件包含“5”: 

<#= 2 + 3 #> 

类功能控制块

类功能控制块定义属性、方法或不应包含在主转换中的所有其他代码。 类功能块常用于编写帮助器函数。 通常,类功能块位于单独的文件中,这样它们可以包含在多个文本模板中。
类功能控制块以 <#+ ... #> 符号分隔,可以简单的认为<#+ ...#>定义的内容为我们的类文件
例如,下面的模板文件声明并使用一个方法:

<#@ 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#> 包含类功能的文件。
类功能块可以包含文本块
可以编写生成文本的方法。

 

 

一名正在抢救的coder

笔名:mangolove

CSDN地址:https://blog.csdn.net/mango_love

GitHub地址:https://github.com/mangoloveYu

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值