T4模板的初级应用
前段时间写过一个很丑的C#代码生成器,用的方法很简单:就是用StringBuilder把一行行的文字代码拼起来,写到一个指定的目录文件中去。我不得不想说,这种方法真糟糕极了,就好像N年我不得不用response.write语句(ASP的一个函数)写一个HTML文档一样难受。所以,今天我在MSDN上找了一些有关T4模板的文档研究了一下,然后,把我原来那个挺丑的C#代码生成器做了更新。
T4模板大至有两种,文档模板和运行时文档模板,它们都可在工程的添加新项目中找到。其中文档模板是在程序的源代码在程序编译前就被使用,可以直接转换成项目的程序源码;运行时文档模板,则会产生一个特别的类,最妙的事情就是这个类是可以扩展的,让你在程序运行的过程中调用,用它来产生各种各样的文档,如:.cs .html .c++等等的各种文本文档。 至于它们的详细用法请参见msdn,输入T4模板就可以找到详细的介绍的。我的代码生成器使用的就是后一种模板,运行时文档模板。
代码及介绍如下:
这个是我用来生成实体类的运行时文档模板
<#@ template language="C#" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Data" #>
namespace <#= NameSpace #>.Model
{
/// <summary>
/// <#= TableName.Substring(0, 1).ToUpper()+TableName.Substring(1) #>:实体类
/// </summary>
[Serializable]
public partial class <#= TableName.Substring(0, 1).ToUpper()+TableName.Substring(1) #>
{
<#
foreach (DataRow dr in TableColumns.Rows) //索引出DataTable表中的columns信息,其实这个表中就两列,列名,列类型
{
string columnName = dr["COLUMN_NAME"].ToString(); //
string dataType;
switch (dr["DATA_TYPE"].ToString()) //数据库的数据类型转换为对应的C#的数据类型,不是很完整
{
case "datetime":
case "smalldatetime":
dataType = "DateTime";
break;
case "int":
case "smallint":
dataType = "int";
break;
case "bit":
dataType = "bool";
break;
case "float":
dataType = "double";
break;
case "decimal":
case "money":
case "smallmoney":
case "numeric":
dataType = "decimal";
break;
case "uniqueidentifier":
dataType = "Guid";
break;
default:
dataType = "string";
break;
}
#>
//嵌套的的C#代码,和ASP真是像极了,不亏500年前是一家人啊
private <#= dataType #> _<#= columnName #>;
public <#= dataType #> <#= columnName.Substring(0, 1).ToUpper()+columnName.Substring(1) #>
{
set { _<#= columnName #> = value; }
set { return _<#= columnName #>; }
}
<#
}
#>
}
<#@ import namespace="System" #>
<#@ import namespace="System.Data" #>
namespace <#= NameSpace #>.Model
{
/// <summary>
/// <#= TableName.Substring(0, 1).ToUpper()+TableName.Substring(1) #>:实体类
/// </summary>
[Serializable]
public partial class <#= TableName.Substring(0, 1).ToUpper()+TableName.Substring(1) #>
{
<#
foreach (DataRow dr in TableColumns.Rows) //索引出DataTable表中的columns信息,其实这个表中就两列,列名,列类型
{
string columnName = dr["COLUMN_NAME"].ToString(); //
string dataType;
switch (dr["DATA_TYPE"].ToString()) //数据库的数据类型转换为对应的C#的数据类型,不是很完整
{
case "datetime":
case "smalldatetime":
dataType = "DateTime";
break;
case "int":
case "smallint":
dataType = "int";
break;
case "bit":
dataType = "bool";
break;
case "float":
dataType = "double";
break;
case "decimal":
case "money":
case "smallmoney":
case "numeric":
dataType = "decimal";
break;
case "uniqueidentifier":
dataType = "Guid";
break;
default:
dataType = "string";
break;
}
#>
//嵌套的的C#代码,和ASP真是像极了,不亏500年前是一家人啊
private <#= dataType #> _<#= columnName #>;
public <#= dataType #> <#= columnName.Substring(0, 1).ToUpper()+columnName.Substring(1) #>
{
set { _<#= columnName #> = value; }
set { return _<#= columnName #>; }
}
<#
}
#>
}
这个T4模板对应的类
namespace Code2Creater.MODEL
{
partial class Model
{
public string NameSpace //命名空间
{
get;
set;
}
public string TableName //表名称,对应类名称
{
get;
set;
}
public DataTable TableColumns //表中各列的定义
{
get;
set;
}
}
{
partial class Model
{
public string NameSpace //命名空间
{
get;
set;
}
public string TableName //表名称,对应类名称
{
get;
set;
}
public DataTable TableColumns //表中各列的定义
{
get;
set;
}
}
上面的类只是定义的几个属性,它对应着模板中的变量引用,微软的这个东西真的设计的很人性化。
最后,是关于这个模板的调用代码,它用来生成实体文件:
public void CreateModelFile(string nameSpace, string table,string filePath)
{
Model m = new Model(); //就是这个类,它和模板文件同名的,上面一段代码的扩展也是一样的类名
m.NameSpace = nameSpace;
m.TableName = table;
m.TableColumns = GetColumns(table); //GetColumns方法是我自己写的一个获取数据表所有列的方法,很简单,就不再附代码了
string fileContent = m.TransformText(); //获取模板生成的文件内容,这个方法是VS自动生成的,很HAPPY啊
string fileName = table + ".cs";
string fPath = Path.Combine(filePath, "MODEL");
Directory.CreateDirectory(fPath);
File.WriteAllText(Path.Combine(fPath, fileName), fileContent); //写入到文件中
}
Model m = new Model(); //就是这个类,它和模板文件同名的,上面一段代码的扩展也是一样的类名
m.NameSpace = nameSpace;
m.TableName = table;
m.TableColumns = GetColumns(table); //GetColumns方法是我自己写的一个获取数据表所有列的方法,很简单,就不再附代码了
string fileContent = m.TransformText(); //获取模板生成的文件内容,这个方法是VS自动生成的,很HAPPY啊
string fileName = table + ".cs";
string fPath = Path.Combine(filePath, "MODEL");
Directory.CreateDirectory(fPath);
File.WriteAllText(Path.Combine(fPath, fileName), fileContent); //写入到文件中
}
对了T4模板还支持一个重要的语句:<#@include file="CommonHeader.txt" #>。这下,我的代码生成器的 自由定制程序模板功能也变得很容易实现了。
最后想说的就是:T4模板真的很好用!