次の方法で共有


T4 テキスト テンプレートの作成

テキスト テンプレートには、そこから生成されるテキストが含まれています。 たとえば、Web ページを作成するテンプレートには、"<html>..." が含まれます。および HTML ページの他のすべての標準部分。 テンプレートに挿入される コントロール ブロックは、プログラム コードのフラグメントです。 コントロール ブロックはさまざまな値を提供し、テキストの一部を条件付きにして繰り返せるようにします。

生成されたファイルのプロトタイプから始めて、結果を変える制御ブロックを段階的に挿入できるため、この構造によりテンプレートの開発が容易になります。

テキスト テンプレートは、次の部分で構成されます。

  • ディレクティブ - テンプレートの処理方法を制御する要素。

  • テキスト ブロック - 出力に直接コピーされるコンテンツ。

  • コントロール ブロック - 変数値をテキストに挿入し、テキストの条件付き部分または繰り返し部分を制御するプログラム コード。

このトピックの例を試すには、「 T4 テキスト テンプレートを使用したコード生成のDesign-Time」の説明に従って、テンプレート ファイルにコピーします。 テンプレート ファイルを編集した後、それを保存し、出力 .txt ファイルを調べます。

指示事項

テキスト テンプレート ディレクティブは、変換コードと出力ファイルを生成する方法に関する一般的な手順をテキスト テンプレート エンジンに提供します。

たとえば、次のディレクティブは、出力ファイルに .txt 拡張子が必要であることを指定します。

<#@ output extension=".txt" #>

ディレクティブの詳細については、「 T4 テキスト テンプレート ディレクティブ」を参照してください。

テキスト ブロック

テキスト ブロックは、出力ファイルにテキストを直接挿入します。 テキスト ブロックに特別な書式はありません。 たとえば、次のテキスト テンプレートでは、"Hello" という単語を含むテキスト ファイルが生成されます。

<#@ output extension=".txt" #>
Hello

コントロールブロック

制御ブロックは、テンプレートの変換に使用されるプログラム コードのセクションです。 既定の言語は C# ですが、Visual Basic を使用するには、ファイルの先頭に次のディレクティブを記述できます。

<#@ template language="VB" #>

コントロール ブロックでコードを記述する言語は、生成されるテキストの言語とは無関係です。

標準制御ブロック

標準制御ブロックは、出力ファイルの一部を生成するプログラム コードのセクションです。

テンプレート ファイルには、任意の数のテキスト ブロックと標準コントロール ブロックを混在させることができます。 ただし、1 つのコントロール ブロックを別のコントロール ブロック内に配置することはできません。 各標準制御ブロックは、 <# ... #>シンボルで区切られます。

たとえば、次の制御ブロックとテキスト ブロックでは、出力ファイルに "0、1、2、3、4 Hello!" という行が含まれます。

<#
    for(int i = 0; i < 4; i++)
    {
        Write(i + ", ");
    }
    Write("4");
#> Hello!

明示的な Write() ステートメントを使用する代わりに、テキストとコードをインターリーブできます。 次の例では、"Hello!" が 4 回出力されます。

<#
    for(int i = 0; i < 4; i++)
    {
#>
Hello!
<#
    }
#>

Write(); ステートメントがコード内で許可される場所であればどこでも、テキスト ブロックを挿入できます。

ループや条件付きなどの複合ステートメント内にテキスト ブロックを埋め込む場合は、常に中かっこ {...} を使用してテキスト ブロックを含めます。

式コントロール ブロック

式制御ブロックは、式を評価して文字列に変換します。 これは出力ファイルに挿入されます。

式制御ブロックは<#= ... #>の記号で囲まれています。

たとえば、次の制御ブロックでは、出力ファイルに "5" が含まれます。

<#= 2 + 3 #>

開始記号には 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 ディレクティブは、C# の using 句または Visual Basic の imports 句と同じです。 これにより、完全修飾名を使用せずにコード内の型を参照できます。

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

必要な数の assembly および import ディレクティブを使用できます。 テキスト ブロックとコントロール ブロックの前に配置する必要があります。

詳細については、「 T4 Import ディレクティブ」を参照してください。

コードとテキストを含む

include ディレクティブは、別のテンプレート ファイルからテキストを挿入します。 たとえば、このディレクティブは、 test.txtの内容を挿入します。

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

含まれるコンテンツは、インクルード テキスト テンプレートの一部であるかのように処理されます。 ただし、include ディレクティブの後に通常のテキストおよび標準コントロール ブロックが続く場合でも、クラス フィーチャ ブロック <#+...#> を含むファイルを含めることができます。

詳細については、「 T4 Include ディレクティブ」を参照してください。

ユーティリティ メソッド

コントロール ブロックで常に使用できる 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()を使用します。 また、hostspecific="true" ディレクティブでtemplateを設定する必要があります。

<#@ 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 を提供する必要があります。

(これは、残りのコードと共にコンパイルされるコードを提供する ランタイム テキスト テンプレートには当てはまりません)。

テンプレートの編集

特殊なテキスト テンプレート エディターは、拡張機能マネージャー オンライン ギャラリーからダウンロードできます。 [ ツール ] メニューの [ 拡張機能マネージャー] をクリックします。 [ オンライン ギャラリー] をクリックし、検索ツールを使用します。