前段時間寫過一個很丑的C#代碼生成器,用的方法很簡單:就是用StringBuilder把一行行的文字代碼拼起來,寫到一個指定的目錄文件中去。我不得不想說,這種方法真糟糕極了,就好像N年我不得不用response.write語句(ASP的一個函數)寫一個HTML文檔一樣難受。所以,今天我在MSDN上找了一些有關T4模板的文檔研究了一下,然后,把我原來那個挺丑的C#代碼生成器做了更新。
T4模板大至有兩種,文檔模板和運行時文檔模板,它們都可在工程的添加新項目中找到。其中文檔模板是在程序的源代碼在程序編譯前就被使用,可以直接轉換成項目的程序源碼;運行時文檔模板,則會產生一個特別的類,最妙的事情就是這個類是可以擴展的,讓你在程序運行的過程中調用,用它來產生各種各樣的文檔,如:.cs .html .c++等等的各種文本文檔。 至於它們的詳細用法請參見msdn,輸入T4模板就可以找到詳細的介紹的。我的代碼生成器使用的就是后一種模板,運行時文檔模板。
代碼及介紹如下:
這個是我用來生成實體類的運行時文檔模板
<#@ 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模板對應的類
{
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); //寫入到文件中
}
對了T4模板還支持一個重要的語句:<#@include file="CommonHeader.txt" #>。這下,我的代碼生成器的 自由定制程序模板功能也變得很容易實現了。
最后想說的就是:T4模板真的很好用!
