用T4 Template生成代码
1 T4语法
T4的语法与ASP.NET的方式比较类似。主要包括指令、文本块、控制块。
1.1 指令
指令主要包括template, output, assembly, import, include等类型,用以告诉T4引擎如何编译和运行一个模板。这些指令相当于T4引擎的配置参数。
示例:
<#@ template debug="true" hostspecific="true" language="C#" #>
告诉T4引擎控制块用c#编写;
<#@ output extension=".cs" #>
告诉T4引擎生成文件的后缀名是.cs;
<#@ assembly name="System.Core"#>
告诉T4引擎编译运行时引用System.Core程序集;
<#@ assembly name="$(SolutionDir)Project.CodeGeneratorinDebugMySql.Data.Dll" #>
告诉T4引擎引用一个特定的位置上的程序集;
<#@ import namespace="System.Data.SqlClient"#>
告诉T4引擎编译运行时引用某个名称空间
<#@ include file="../Code/DBSchema.ttinclude"#>
告诉T4引擎编译运行时引用某个文件,类似于JS的引用
1.2 文本块
文本块, T4引擎会将文本块的内容直接复制到输出文件中。
1.3 控制块
控制块,主要用于控制文本的输出。在控制块可以写任意的C#代码。
1.4 示例Hello world
<#@ template debug="true" hostspecific="true" language="C#" #> <#@ output extension=".txt" #> Hello, <#Write("World");#>
2 工作原理
转载自:http://www.olegsych.com/2007/12/text-template-transformation-toolkit/
1> Step1:编译模板,根据指令编译模板中的文本块和控制块,并生成一个继承于TextTransformation的类。
2> Step2: T4引擎动态创建类的实例,并调用TransformText方法。
3 在T4中读取表结构
我们用T4时,主要是基于数据库或配置文件来生成各类的代码。所以如何有效地获取数据库的结构信息,是比较重要的。 之前看很多人直接把获取数据库的信息放在每一个模板中,在更换其它数据库时,又要重写模板。一个模板同时支持多个项目时,不同的项目数据库很有可能是不同的。
主要设计思想如下,简单地应用了简单工厂模式。通过DBSchemaFactory类根据不同数据库类型,获取数据库访问类的接口IDBSchema。最后返回相同的表结构信息。
DBSchema.ttinclude类:
根据不同的数据库,获取表结构信息。已包括SQLSERVER和MYSQL。
数据库结构的测试模板02 DBSchema.tt
输出数据库的所有表的结构信息
注:
1> 在DBSchema.ttinclude,所有的类都被包含在<#+ #>中,<#+ #>是一个类功能的控制块,其中可以定义任意的C#代码。这些类多是帮助类,所以又定义在一个可复用的模板中”.ttinclude”.
2> 在02 DBSchema.tt中有一行” <#@ include file="../Code/DBSchema.ttinclude"#>“,是指引用某个位置的文件,在这里指是引用一个可复用的模板。
4用T4生成实体
用T4生成一个代码的一个常用应用是生成实体类,下面是一个示例代码(此模板引用了DBSchema.ttinclude):
注:
1> 在这个模板中,<#= #>为表达式控制块
2> 除了表达式控制块,其它的代码块的开始<#和结束符#>最好是放在行首,这样一来容易分辨,二来最终输出的文本也是你想要的,不然文本块会乱掉。
5生成多个实体并分隔成多个文件
对于同时生成多个文件的模板可以直接下面的一个帮助类,这个帮助类可以帮助我们将一个文件分隔成多个文件(网上找的)。
分隔文件的帮助类:
示例模板:
生成某个数据库下面所有的表的实体,并放在不同的文件里。
6 其它
T4的编辑工具下载地址http://t4-editor.tangible-engineering.com/Download_T4Editor_Plus_ModelingTools.html
VS默认的编辑工具无高亮,无提示,错误不易定位。 没这个工具,真心不想写任何T4代码。
所有示例代码: CodeGenerator.zip