目录:
- T4概念
- 文本模板两种类型
- 文本模板的组成
- 案例
1.T4
一种可以由自己去自定义规则的代码生成器。可生成任何形式的文本文件或供程序调用的字符串。
注意:在VS中T4模板是没有智能提示和颜色标注的,可以安装官方推荐插件:tangibleT4EditorPlusModellingTools
1.1 文本模板有两种类型
- 设计时模版
以便定义应用程序的部分源代码和其他资源。读取单个输入文件或数据库中的数据的多个模板,并生成一些源文件。 每个模板都生成一个文件。
①向您的项目中添加"文本模板"文件。
②添加纯文本文件并将其"自定义工具"属性设置为"TextTemplatingFileGenerator"。
- 运行时模版
以便生成文本字符串
①若要创建运行时模板,请向您的项目中添加"已预处理的文本模板"文件。
②还可以添加纯文本文件并将其"自定义工具"属性设置为"TextTemplatingFilePreprocessor"。
1.2 文本模板的组成
- 指令
①模版指令
<#@ template debug="false" hostspecific="false" language="C#" #>
//可选,hostspecific如果将此特性设为true,则会将名为Host的属性添加到由文本模板生成的类中。
是对象转换引擎的宿主的引用,并声明为Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost 类型。
②参数指令
<#@ parameter type="Full.TypeName" name="ParameterName" #>
//用来传参,出现在运行时模板中
③输出指令
<#@ output extension=".fileNameExtension" [encoding="encoding"] #>
//用于设置输出文件的后缀名和文件编码。extension:输出文件扩展名,默认为".cs"encoding:文件编码,默值为utf-8。
④程序集指令
<#@ assembly name="System.Core" #>
程序集指令相当于VS里面我们添加程序集引用的功能。T4模版的程序集引用是完全独立的。
可以使用 $(variableName) 语法引用 Visual Studio的变量。几个常用的变量:
$(SolutionDir):当前项目所在解决方案目录
$(ProjectDir):当前项目所在目录
$(TargetPath):当前项目编译输出文件绝对路径
$(TargetDir):当前项目编译输出目录,即web项目的Bin目录
⑤导入指令
<#@ import namespace="namespace" #>
//import 指令允许您在不提供完全限定名称的情况下引用另一个命名空间中的元素。 它等效于 C# 中的 using。
⑥包含指令
<#@ include file="filePath" #>
//包含指令可以提高代码复用率,比如我们可以将一些常用的程序集、命名空间引用放到一个文件里,使用时仅需要引用下即可
⑦文本块
<#@ output extension=".txt" #> Hello World!
//文本块直接向输出文件插入文本。 文本块没有特殊格式。
- 控制模块
控制块是用于转换模板的程序代码节
①标准控制块
生成输出文件部件的程序代码节。
<#可以混合使用任意数量的文本块和标准控制块。控制块不能嵌套控制块,以 “<# ... #>”分隔
for(int i = 0; i < 4; i++)
{
Write(i + ", ");
}
Write("4");
#>
Hello!
//也可以交错文本和代码,而不必使用显式 Write() 语句。 以下示例输出"Hello!"四次:
<#
for(int i = 0; i < 4; i++)
{
#>
Hello!
<#
}
#>
②表达式控制块
计算表达式并将其转换为字符串。 该字符串将插入到输出文件中。
<#= 2 + 3 #> //包含5。表达式控制块以 <#= ... #> 符号分隔。
③类功能控制块
定义属性、方法或不应包含在主转换中的所有其他代码。常用于编写帮助器函数。类功能块位于单独的文件中,包含在多个文本模板中。
//声明使用 以 <#+ ... #> 符号分隔
<#@ 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.
<#+ // 定义方法
private int Square(int i)
{
return i*i;
}
#>
1.3案例:创建模型
可以借助 DbHelper.ttinclude 和 Manager.ttinclude 两个第三方资源提高T4模板的开发效率。(安装命令:Install-Package T4 -Version 2.0.1)
DbHelper.ttinclude 的主要方法:
- DbHelper.GetDbTables() :获取指定数据库的所有表。
- DbHelper.GetDbColumns():获取指定表的所有列。
Manager.ttinclude 的主要方法:
- Create(): 获取该类的一个实例。
- StartNewFile():新建一个文件。
- Process(true):生成文件。
另外,数据库的连接字符串在Config类(DbHelper.ttinclude 文件)中。
生成T4模板代码:
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Data.dll" #>
<#@ assembly name="System.Data.DataSetExtensions.dll" #>
<#@ import namespace="System.Data" #>
<#@ import namespace="System.Data.SqlClient" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
<#@ include file="../Common/CodeTemplates/DbHelper.ttinclude"#>
<#@ include file="../Common/CodeTemplates/Manager.ttinclude"#>
<#
var manager = Manager.Create(Host, GenerationEnvironment);
var tables=DbHelper.GetDbTables(Config.ConnectionString,Config.DbDatabase);
foreach (DbTable table in tables)
{
manager.StartNewFile(table.TableName+".cs");
#>
using System;
namespace Model
{
public class <#=table.TableName#>
{
<#
foreach(var col in DbHelper.GetDbColumns(Config.ConnectionString,Config.DbDatabase,table.TableName))
{
#>
public <#=col.CSharpType#><# if(col.CommonType.IsValueType && col.IsNullable){#>?<#}#> <#=col.ColumnName#> { get; set; }
<#
}
#>
}
}
<#
}
manager.Process(true);
#>