共用方式為


編寫 T4 文本模板

文字範本包含將從中產生的文字。 例如,建立網頁的範本將包含「<html>...」以及 HTML 頁面的所有其他標準部分。 插入模板的是 控制塊,它們是程式代碼的片段。 控制塊提供不同的值,並允許部分文字有條件和重複。

此結構使範本易於開發,因為您可以從所產生檔案的原型開始,並以增量方式插入可改變結果的控制區塊。

文字範本由下列部分組成:

  • 指令 - 控制範本處理方式的元素。

  • 文字區塊 — 直接複製到輸出的內容。

  • 控制區塊 - 將變數值插入文字中,並控制文字的條件或重複部分的程式代碼。

若要嘗試本主題中的範例,請將它們複製到範本檔案中,如 使用 T4 文字範本產生Design-Time 程式碼中所述。 編輯範本檔案後,儲存它,然後檢查輸出 .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!
<#
    }
#>

類別特性控制區塊

類別功能控制區塊會定義屬性、方法或任何其他不應包含在主要轉換中的程式碼。 類別功能區塊經常用於協助程式函式。 通常,類別特徵區塊會放置在單獨的檔案中,以便它們可以 包含在 多個文字樣板中。

類別特徵控制區塊由符號分隔 <#+ ... #>

例如,下列範本檔案會宣告並使用方法:

<#@ 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 #>.
<#+
}
#>

將產生文字的方法放在可由多個範本包含的個別檔案中特別有用。

使用外部定義

組件

範本的程式碼區塊可以使用定義最常用的 .NET 元件的類型,例如 System.dll。 此外,您可以參考其他 .NET 元件或您自己的元件。 您可以提供路徑名稱,或元件的強式名稱:

<#@ assembly name="System.Xml" #>

您應該使用絕對路徑名稱,或在路徑名稱中使用標準巨集名稱。 例如:

<#@ assembly name="$(SolutionDir)library\MyAssembly.dll" #>

組合指示詞在 預先處理的文字範本中沒有作用。

如需詳細資訊,請參閱 T4 元件指令

命名空間

import 指示詞與 using C# 中的子句或 imports Visual Basic 中的子句相同。 它允許您在程式碼中引用類型,而無需使用完全限定的名稱:

<#@ import namespace="System.Xml" #>

您可以根據需要使用任意數量 assembly 的 和 import 指令。 您必須將它們放在文字和控制塊之前。

如需詳細資訊,請參閱 T4 匯入指示詞

包括程式碼和文字

指令 include 插入來自另一範本檔案的文字。 例如,此指引會插入test.txt的內容。

<#@ include file="c:\test.txt" #>

包含的內容幾乎會像包含文字範本的一部分一樣進行處理。 不過,您可以包含包含類別特徵區塊 <#+...#> 的檔案,即使 include 指示詞後面跟著一般文字和標準控制區塊。

如需詳細資訊,請參閱 T4 包含指示

實用方法

控制塊中有多種方法,例如 Write(),是您始終可以使用的。 它們包括幫助您縮排輸出和報告錯誤的方法。

您也可以撰寫自己的公用程式方法集。

如需詳細資訊,請參閱文字 範本公用程式方法

轉換資料和模型

文字範本最有用的應用程式是根據來源(例如模型、資料庫或資料檔案)的內容產生材料。 您的範本會擷取並重新格式化資料。 範本集合可以將這類來源轉換成多個檔案。

有數種方法可以讀取原始檔。

讀取文字範本中的檔案。 這是將資料放入範本的最簡單方法:

<#@ import namespace="System.IO" #>
<# string fileContent = File.ReadAllText(@"C:\myData.txt"); ...

將檔案載入為可導覽模型。 更強大的方法是將資料讀取為模型,您的文字範本程式碼可以導航該模型。 例如,您可以載入 XML 檔案並使用 XPath 運算式對其進行導覽。 您也可以使用 xsd.exe 來建立一組類別,您可以使用這些類別來讀取 XML 資料。

在圖表或表單中編輯模型檔案。 Domain-Specific 語言工具提供的工具可讓您將模型編輯為圖表或 Windows 表單。 這使得與生成應用程序的用戶討論模型變得更加容易。 Domain-Specific 語言工具也會建立一組反映模型結構的強型別類別。 如需詳細資訊,請參閱 從 Domain-Specific 語言產生程式碼

設計階段範本中的相對檔案路徑

設計階段文字範本中,如果您想要參考相對於文字範本位置的檔案,請使用 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 #>

您也可以取得主機提供的其他服務。 如需詳細資訊,請參閱 從範本存取 Visual Studio 或其他主機

設計階段文字範本會在個別的 AppDomain 中執行

您應該注意, 設計階段文字範本 會在與主要應用程式不同的 AppDomain 中執行。 在大部分情況下,這並不重要,但您可能會在某些複雜情況下發現限制。 例如,如果您想要從個別服務將資料傳入或傳出範本,則服務必須提供可序列化的 API。

(這不適用於 執行階段文字範本,它提供的程式碼會與程式碼的其餘部分一起編譯。)

編輯範本

可以從 Extension Manager Online Gallery 下載專門的文字範本編輯器。 在 [工具] 功能表上,按一下 [擴充功能管理員]。 按一下 [線上圖庫],然後使用搜尋工具。