原文:http://www.cnblogs.com/lzrabbit/archive/2012/07/15/2591085.htmlhtml
額,T4好陌生的名字,和NuGet同樣很悲催,不爲世人所熟知,卻又在背後默默無聞的奉獻着,直到如今咱們項目組的人除了我以外,其它人仍是對其豪無興趣,基本上是連看一眼都懶得看,可憐的娃啊。。。web
T4(Text Template Transformation Toolkit)是微軟官方在VisualStudio 2008中開始使用的代碼生成引擎。在 Visual Studio 中,「T4 文本模板」是由一些文本塊和控制邏輯組成的混合模板,它能夠生成文本文件。 在 Visual C# 或 Visual Basic 中,控制邏輯編寫爲程序代碼的片斷。生成的文件能夠是任何類型的文本,例如網頁、資源文件或任何語言的程序源代碼。如今的VS中只要與代碼生成相關的場景基本上都能找T4的身影,好比MVC的視圖模板,Entity Framwork的DataContext模板等等。數據庫
在學習枯燥的概念前咱們先來看一下用T4模版快速生成POCO實體類的示例
打開VS2010建一個項目,而後右擊項目文件選擇新建項,在文件列表中找到文件模版,如圖所示函數
修改TextTemplate1.tt文件內容以下工具
<#@ template debug="false" hostspecific="false" language="C#" #> <#@ output extension=".cs" #> using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { public class User { /// <summary> /// 用戶ID /// </summary> public int UserID { get; set; } /// <summary> /// 用戶名 /// </summary> public string UserName { get; set; } /// <summary> /// 密碼 /// </summary> public string Password { get; set; } /// <summary> /// Email /// </summary> public string Email { get; set; } /// <summary> /// 手機號 /// </summary> public string Mobile { get; set; } } }
點擊Ctrl+S而後能夠看到自動生成了一個TextTemplate1.cs文件學習
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { public class User { /// <summary> /// 用戶ID /// </summary> public int UserID { get; set; } /// <summary> /// 用戶名 /// </summary> public string UserName { get; set; } /// <summary> /// 密碼 /// </summary> public string Password { get; set; } /// <summary> /// Email /// </summary> public string Email { get; set; } /// <summary> /// 手機號 /// </summary> public string Mobile { get; set; } } }
是否是很神奇,T4模版引擎會根據你在模版裏定義的內容自動生成相應的文件,固然本示例過於簡單,徹底不能展示T4的強大,當你若真正瞭解T4後,會發現神馬代碼生成器全都是浮雲,T4纔是王道,利用T4你徹底能夠輕鬆生成屬於本身風格的任何類型代碼,在下篇文章會有實例展現如何經過T4鏈接數據庫自動生成POCO類,基本上這個纔是咱們用T4的最大意圖,呵呵,在這以前仍是老老實實看看枯燥乏味的T4基礎知識吧。測試
可在應用程序中執行運行時 T4 文本模板(「預處理過的」模板)以便生成文本字符串(一般做爲其輸出的一部分)。ui
若要建立運行時模板,請向您的項目中添加「已預處理的文本模板」文件。 另外,您還能夠添加純文本文件並將其「自定義工具」屬性設置爲「TextTemplatingFilePreprocessor」。this
有關更多信息,請參見使用預處理 T4 文本模板生成運行時文本。 有關模板語法的更多信息,請參見編寫 T4 文本模板。編碼
在 Visual Studio 中執行設計時 T4 文本模板,以便定義應用程序的部分源代碼和其餘資源。
一般,您可使用讀取單個輸入文件或數據庫中的數據的多個模板,並生成一些 .cs、.vb 或其餘源文件。 每一個模板都生成一個文件。 在 Visual Studio 或 MSBuild 內執行它們。
若要建立設計時模板,請向您的項目中添加「文本模板」文件。 另外,您還能夠添加純文本文件並將其「自定義工具」屬性設置爲「TextTemplatingFileGenerator」。
有關更多信息,請參見使用 T4 文本模板生成設計時代碼。 有關模板語法的更多信息,請參見編寫 T4 文本模板。
<#@ template [language="C#"] [compilerOptions="options"] [culture="code"] [debug="true"] [hostspecific="true"] [inherits="templateBaseClass"] #>
<#@ parameter type="Full.TypeName" name="ParameterName" #>
顧名思義,就是用來傳參的,應該是用在運行時模版的(預處理模版)
<#@ output extension=".fileNameExtension" [encoding="encoding"] #>
比較重要的指令,用於設置輸出文件的後綴名和文件編碼
extension:輸出文件擴展名,默認爲".cs"
encoding:文件編碼,默值爲utf-8(這裏不能肯定,我測試是utf-8)
<#@ assembly name="[assembly strong name|assembly file name]" #>
$(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\
<#@ import namespace="namespace" #>
在 Visual Studio T4 文本模板的代碼塊中,import 指令容許您在不提供徹底限定名稱的狀況下引用另外一個命名空間中的元素。 它等效於 C# 中的 using 或 Visual Basic 中的 imports。默認已經導入了System命名空間的引用。
<#@ include file="filePath" #>
<#@ 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" #>
文本塊直接向輸出文件插入文本。 文本塊沒有特殊格式。 例如,下面的文本模板將生成一個包含單詞「Hello World!」的文本文件:
<#@ 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() 語句。 如下示例輸出「Hello!」四次:
<# for(int i = 0; i < 4; i++) { #> Hello! <# } #>
在代碼中,可使用 Write(); 語句的位置均可以插入文本塊。
表達式控制塊計算表達式並將其轉換爲字符串。 該字符串將插入到輸出文件中。
表達式控制塊以 <#= ... #> 符號分隔。
例如,若是使用下面的控制塊,則輸出文件包含「5」:
<#= 2 + 3 #>
請注意,開始符號有三個字符「<#=」。
表達式能夠包含做用域中的任何變量。 例如,下面的塊輸出數字行:
<#@ output extension=".txt" #> <# for(int i = 0; i < 4; i++) { #> This is hello number <#= i+1 #>: Hello! <# } #>
類功能控制塊定義屬性、方法或不該包含在主轉換中的全部其餘代碼。 類功能塊經常使用於編寫幫助器函數。 一般,類功能塊位於單獨的文件中,這樣它們能夠包含在多個文本模板中。
類功能控制塊以 <#+ ... #> 符號分隔,能夠簡單的認爲<#+ ...#>定義的內容爲咱們的類文件
例如,下面的模板文件聲明並使用一個方法:
<#@ 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#> 包含類功能的文件。
類功能塊能夠包含文本塊
能夠編寫生成文本的方法。 例如:
List of Squares:
<# for(int i = 0; i < 4; i++) { WriteSquareLine(i); } #> End of list. <#+ // Class feature block private void WriteSquareLine(int i) { #> The square of <#= i #> is <#= i*i #>. <# } #>
將文本生成方法放置在可供多個模板包含的單獨文件中,是很是有用的。
嗯,大概的基礎點應該就這些了,更多的本身去MSDNhttp://msdn.microsoft.com/zh-cn/library/bb126445詳細瞭解吧
這裏解釋點容易讓人困惑的地方,咱們在T4模版裏面引用的程序集和那些命名空間都是利用T4生成代碼須要使用的,也就是T4模版要用的,和咱們要生成的目標類毛關係都沒有,當初爲搞清楚這點但是費了不精力。T4初看起來很複雜,其實稍微花些心思研究下,主要彷佛把MSDN看懂仍是很容易學會的,一旦掌握了受用無窮