因為這段時間一直都沒空,我也不知道有沒有對人T4感興趣,但不管了,先記下在說吧,就當是我的筆記。
希望對你們有用。
如果你對T4還比較陌生,推薦你在復習幾篇文章:
One:T4系列文章之1:認識T4
Two:T4系列文章之2:T4工具簡介、調試以及T4運行原理
復習復習。。
T4語言的語法很簡單,可以說一學就會。它不像C#或者JAVA一樣,那么多的限制什么的。所以,只要會C#語言,然后再學習一點T4它應該注意的地方,那么就OK了。
是不是很心動了?心動不如行動吧。
T4模板的基本結構: 它們基本上可以分成5類:指令塊(Directive Block)、文本塊(Text Block)、代碼語句塊(Statement Block)、表達式塊(Expression Block)和類特性塊(Class Feature Block)。
你看上面的截圖,把一些基本的都羅列出來了。
1、指令塊(Directive Block)
首先,值需要記住的是 指令塊是已@開頭的。 比如你看到的下面。
和ASP.NET頁面的指令一樣,它們出現在文件頭,通過<#@…#>表示。其中<#@ template …#>指令是必須的,用於定義模板的基本屬性,比如編程語言、基於的文化、是否支持調式等等。比較常用的指令還包括用於程序集引用的<#@ assembly…#>,用於導入命名空間的<#@ import…#>等等。
它主要包括以下內容:
1. <#@ import#>
開頭,這個主要表示是說引入命名空間 比如:<#@ import namespace="System.Linq" #>
2. <#@ assembly name="[assembly strong name|assembly file name]" #>
顧名思義 指的是 引入ddl文件,比如<#@ assembly name="System.Core.dll" #>。不過這里其實沒有必要,因為你只要在當前的引用里添加dll文件就ok了。 3. <#@ output extension="" #>
這個是你輸出的格式,比如<#@ output extension=".cs" #>,那么你輸出的就是.cs文件咯。很好理解。Extension是擴展名的意思嘛。
5. <#@ template #>
格式:<#@ template [language="VB"] [hostspecific="true"] [debug="true"] [inherits="templateBaseClass"] [culture="code"] [compilerOptions="options"] #>
它主要有2個意思:一個只的是寫模板所使用的語言,比如<#@ template language="C#" #> 那么我這個模板可以用C#來些。
另一個很重要的特性指的是:繼承。就是把一些公共的方法抽象到父模板中,然后可以在多個模板中進行復用。這個非常有用,我以后會逐步的介紹。 比如:<#@ template language="C#" inherits="CommonTemplate" debug="true" #> CommonTemplate是我寫的一個公共模板。
6. <#@ include file="" #>
這個很有意思,意思就是說在當前的模板中包含另外一個文件中的內容。先來一個很簡單的例子。
6.1 新建一個空白的文本模板 ,命名為:MyTextTemplate.tt
6.2 在新建一個 txt文件,里面寫入一些字。myText.txt
6.3 在MyTextTemplate.tt模板中,<#@ include file=”myText.txt”#>
6.4 然后你就可以在MyTextTemplate.tt看到 你文本中的一些字符。
對第六點需要的注意事項:
- file的路徑可以是絕對路徑、相對路徑。
2.file可以包括環境變量,但它必須用%包起來。比如<#@ include file="%HOMEPATH%\MyIncludeFile.t4" #>
3.file后面的文件的擴展名不能包括 .tt結尾的。
如果你需要用.tt的結尾,你需要用4t來代替。這是因為如果你加了.tt后綴的文件名,因為vs會自動是把當前.tt的文件的Custom Tool(自定義工具)屬性設定為TextTemplatingFileGenerator。
2、文本塊(Text Block)
文本塊就是直接原樣輸出的靜態文本,不需要添加任何的標簽。在上面的模板文件中,處理定義在<#… #>、<#+… #>和<#=… #>中的文本都屬於文本塊。比如在指令塊結束到第一個“<#”標簽之間的內容就是一段靜態的文本塊。
模板內容:
<#@ template language="C#" #> Hello World!
編譯的內容:
using System; using Microsoft.VisualStudio.TextTemplating; namespace Microsoft.VisualStudio.TextTemplating413AE4BE2CE28AB99 { public class GeneratedTextTransformation: TextTransformation { public override string TransformText() { this.Write("Hello World!"); return this.GenerationEnvironment.ToString(); } } }
輸出是:Hello World!
3、代碼語句塊(Statement Block)
代碼語句塊通過<#Statement#>的形式表示,中間是一段通過相應編程語言編寫的程序調用,我們可以通過代碼語句快控制文本轉化的流程。
其實在我們的使用中,對語句塊的作用主要就是寫C#代碼。
比如,請看下面:
<# for(int i = 0; i < 4; i++) { Write(i + ", "); } Write("4"); #> Hello!
那么輸出的結果就是
0,1,2,3,4
Hello!
凡是能在平時我們VS里面書寫的代碼,都可以在<# #>里表示。
4、表達式塊(Expression Block)
表達式塊以<#=Expression#>的形式表示,通過它之際上動態的解析的字符串表達內嵌到輸出的文本中。
模板內容:
<#@ template language="C#" #> <# for(int i = 1; i <= 3; i++) { #> Hello World <#= i #>! <# } #>
請注意這個:<#= i #>
后台編譯的內容:
using System; using Microsoft.VisualStudio.TextTemplating; namespace Microsoft.VisualStudio.TextTemplating76E036EA7C70CB236 { public class GeneratedTextTransformation: TextTransformation { public override string TransformText() { for (int i = 1; i <= 3; i++) { this.Write("Hello World "); this.Write(ToStringHelper.ToStringWithCulture(i)); this.Write("!\r\n"); } return this.GenerationEnvironment.ToString(); } } }
輸出的內容就是:
Hello World 1! Hello World 2! Hello World 3!
5、類特性塊(Class Feature Block)
首先我們需要記住的是 類型性模塊是有個+號的,比如<#+ #>這種類型的。
如果文本轉化需要一些比較復雜的邏輯,我們需要寫在一個單獨的輔助方法中,甚至是定義一些單獨的類,我們就是將它們定義在類特性塊中。類特性塊的表現形式為<#+ FeatureCode #>,對於Hello World模板,得到人名列表的InitializePersonList方法就定義在類特性塊中。
其實說白了 就是在里面寫方法,方便我們多次重用和調用,提高我們的開發效率。
比如:
<#@ template language="C#"#> <# HelloWorld(); #> <# HelloWorld(); #> <#+ private void HelloWorld() { this.Write("Hello World"); } #>
注意上面的+號的上面有個<# HelloWorld(); #> 。
所以,結果理所當然的就是有2個Hello World。
不過,您需要注意的是,你的這個類特性方法應該放到最后面去,比如你這樣用:
<#@ template language="C#"#> <# HelloWorld(); #> <# HelloWorld(); #> <#+ private void HelloWorld() { this.Write("Hello World"); } #> <# HelloWorld(); #>
不好意思,它會給你報錯,
ErrorGeneratingOutput
因為你不是放到最后面了,所以這里需要特別特別特別注意一下。
還有就是類特性的功能里面並 不僅僅只是一個方法,它里面還可以放很多東西,比如屬性、常量、字段以及其他可以在其他編程里看到的C#結構都可以插入里面,我們足足可以見到它有多么強悍的生命力。
比如下面在舉一個例子:
<#@ template language="C#" #> <# HelloWorld(); #> <#+ private string _field = "classy"; private void HelloWorld() { for(int i = 1; i <= 3; i++) { #> Hello <#=_field#> World <#= i #>! <#+ } } #>
輸出的結果就是:
Hello classy World 1!
Hello classy World 2!
Hello classy World 3!
OK。T4語言的就簡單的到這里。寫的比較倉促,希望能得到諒解。有問題可以在討論。謝謝。