撰寫 T4 文字範本
更新:2011 年 3 月
文字範本包含會由它本身產生的文字。 例如,建立網頁的範本將會包含 HTML 網頁的 "<html>…" 及所有其他標準部分。 在範本中會插入「控制區塊」(Control Block),即程式碼片段。 控制區塊可以提供有變化的值,同時允許文字部分附有條件而且可重複。
這種結構能讓範本易於開發,因為您可從產生的檔案原型開始著手,以累加方式插入讓結果有所不同的控制區塊。
文字範本由下列部分組成:
指示詞:控制處理範本方式的項目。
文字區塊:直接複製到輸出中的內容。
控制區塊:用來將變數值插入文字中,以及控制文字之有條件部分和重複部分的程式碼。
若要嘗試本主題中的範例,請將範例複製到範本檔中,如使用 T4 文字範本在設計階段產生程式碼中所述。 編輯過範本檔之後,請加以儲存並檢查 .txt 輸出檔。
指示詞
文字範本指示詞會將如何產生轉換程式碼和輸出檔的一般指令提供給文字範本化引擎。
例如,下列指示詞指定輸出檔應有 .txt 副檔名:
<#@ output extension=".txt" #>
如需指示詞的詳細資訊,請參閱T4 文字範本指示詞。
文字區塊
文字區塊會直接將文字插入至輸出檔。 文字區塊沒有特殊格式。 例如,下列文字範本將會產生包含 "Hello" 這個字的文字檔:
<#@ output extension=".txt" #>
Hello
控制區塊
控制區塊是用來轉換範本的程式碼區段。 預設的語言為 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!
<#
}
#>
類別功能控制區塊
類別功能控制區塊會定義屬性、方法或任何其他不應加入至主要轉換的程式碼。 類別功能區塊經常用於 Helper 函式。 類別功能區塊通常放在不同的檔案中,以便供多個文字範本加入。
類別功能控制區塊是由 <#+ ... #> 符號分隔。
例如,下列範本檔會宣告和使用方法:
<#@ 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 指示詞後面是否有標準區塊或文字都一樣。
如需控制區塊的詳細資訊,請參閱T4 文字範本控制區塊。
類別功能區塊可以包含文字區塊
您可以撰寫產生文字的方法。 例如:
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 #>.
<#
}
#>
將產生文字的方法放置在可供多個範本加入的個別檔案中,會特別有用。
使用外部定義
組件
範本的程式碼區塊可以使用定義為最常用 .NET 組件 (例如 System.dll) 的型別。 此外,您還可以參考其他 .NET 組件或自己的組件。 您可以提供組件的路徑名稱或強式名稱:
<#@ assembly name="System.Xml" #>
您應該使用絕對路徑名稱,或在路徑名稱中使用標準巨集名稱。 例如:
<#@ assembly name="$(SolutionDir)library\MyAssembly.dll" #>
如需巨集的清單,請參閱建置命令和屬性的巨集。
assembly 指示詞在前置處理過的文字範本中無效。
如需詳細資訊,請參閱T4 組件指示詞。
命名空間
import 指示詞與 C# 中的 using 子句或 Visual Basic 中的 imports 子句相同。 您可以在程式碼中參考型別,而不需使用完整名稱:
<#@ import namespace="System.Xml" #>
您可以視需要使用任意數量的 assembly 和 import 指示詞, 但是必須將它們放在文字和控制區塊之前。
如需詳細資訊,請參閱 T4 匯入指示詞。
加入程式碼和文字
include 指示詞會插入來自其他範本檔中的文字。 例如,這個指示詞會插入 test.txt 的內容。
<#@ include file="c:\test.txt" #>
處理所加入的內容時,幾乎可以將此內容當做是進行加入之文字範本的一部分來處理。 而且,不論 include 指示詞後面是否有一般文字或標準控制區塊,您都可以加入包含類別功能區塊 <#+...#> 的檔案。
如需詳細資訊,請參閱 T4 包含指示詞。
公用程式方法
有許多可隨時供您在控制區塊中使用的方法 (例如 Write()) 其中包括協助您縮排輸出或用於報告錯誤的方法。
您也可以撰寫自己的公用程式方法集。
如需詳細資訊,請參閱T4 文字範本公用程式方法。
轉換資料和模型
文字範本最大的功用就是根據來源 (例如模型、資料庫或資料檔) 的內容產生資料。 範本會擷取和重新格式化資料。 範本集合可以將這類來源轉換成多個檔案。
有許多方法可以用來讀取來源檔案。
在文字範本中讀取檔案: 這是範本取得資料最簡單的方法:
<#@ import namespace="System.IO" #>
<# string fileContent = File.ReadAllText(@"C:\myData.txt"); ...
將檔案當做可巡覽的模型載入: 功能較強大的方法是,讀取資料做為可供文字範本程式碼巡覽的模型。 例如,您可以載入 XML 檔,然後搭配 XPath 運算式巡覽該檔案。 您也可以使用 xsd.exe (英文),建立一組可用來讀取 XML 資料的類別。
在圖表或表單中編輯模型檔:Domain-Specific Language Tools 提供可讓您以圖表或 Windows Form 的形式編輯模型的工具。 如此一來,與產生之應用程式的使用者討論模型時,會變得更加輕鬆。 Domain-Specific Language Tools 也會建立一組反映模型結構的強型別類別。 如需詳細資訊,請參閱從網域指定的語言產生程式碼。
使用 UML 模型: 您可以從 UML 模型產生程式碼。 這種方法具備可運用熟悉的標記法以圖表形式編輯模型的優勢。 此外,您並不需要設計圖表。 如需詳細資訊,請參閱 HOW TO:從 UML 模型產生檔案。
相對檔案路徑
如果想要參考位在文字範本之相對位置中的檔案,請使用 this.Host.ResolvePath()。 您也必須在 template 指示詞中設定 hostspecific="true":
<#@ template hostspecific="true" language="C#" #>
<#@ output extension=".txt" #>
<#@ import namespace="System.IO" #>
<#
// Find a path within the same project as the text template:
string myFile = File.ReadAllText(this.Host.ResolvePath("MyFile.txt"));
#>
Content of MyFile.txt is:
<#= myFile #>
您也可以取得主應用程式所提供的其他服務。 如需詳細資訊,請參閱從 T4 文字範本存取 Visual Studio 或其他主機。
文字範本會在不同的 AppDomain 中執行
請注意,文字範本會在與主應用程式不同的 AppDomain 中執行。 在大多數情況下這並不重要,但您可能發現在某些複雜情況下會有所限制。 例如,如果要從不同的服務將資料傳入或傳出範本,則服務必須提供可序列化的 API。
編輯樣板
您可以從「擴充管理員線上圖庫」下載專門的文字範本編輯器。 按一下 [工具] 功能表上的 [擴充管理員]。 按一下 [線上圖庫],然後使用搜尋工具。
相關主題
工作 |
主題 |
---|---|
撰寫範本。 |
|
使用程式碼來產生文字。 |
|
在 Visual Studio 方案中產生檔案。 |
|
在 Visual Studio 外部執行文字產生作業。 |
|
將資料的形式轉換為 Domain-Specific Language。 |
|
撰寫指示詞處理器來轉換自己的資料來源。 |
變更記錄
日期 |
記錄 |
原因 |
---|---|---|
2011 年 3 月 |
在 Assembly 指示詞中使用巨集。 |
客戶回函。 |