T4 テキスト テンプレートを使用した実行時テキスト生成Run-Time Text Generation with T4 Text Templates

実行時に、Visual Studio ランタイムテキストテンプレートを使用して、アプリケーションにテキスト文字列を生成できます。You can generate text strings in your application at run time by using Visual Studio runtime text templates. アプリケーションを実行するコンピューターに Visual Studio がインストールされている必要はありません。The computer where the application executes does not have to have Visual Studio. 実行時テンプレートとも呼ばれる「ランタイム テキスト テンプレート」のため、コンパイル時に、テンプレートからランタイムに実行されるコードが生成されます。Runtime templates are sometimes called "preprocessed text templates" because at compile time, the template generates code that is executed at run time.

各テンプレートは、生成される文字列として現れるテキストと、プログラム コードのフラグメントの組み合わせです。Each template is a mixture of the text as it will appear in the generated string, and fragments of program code. プログラムのフラグメントは、文字列の変数部分の値の指定と、条件と繰り返し部分を制御します。The program fragments supply values for the variable parts of the string, and also control conditional and repeated parts.

たとえば、次のテンプレートは、HTML レポートを作成するアプリケーションで使用され得るものです。For example, the following template could be used in an application that creates an HTML report.

<#@ template language="C#" #>
<html><body>
<h1>Sales for Previous Month</h2>
<table>
    <# for (int i = 1; i <= 10; i++)
       { #>
         <tr><td>Test name <#= i #> </td>
             <td>Test value <#= i * i #> </td> </tr>
    <# } #>
 </table>
This report is Company Confidential.
</body></html>

テンプレートが、変数部分がプログラム コードにより置き換えらた HTML ページとなっていることに注目してください。Notice that the template is an HTML page in which the variable parts have been replaced with program code. 静的な HTML ページのプロトタイプを記述することで、このようなページのデザインを始めることができます。You could begin the design of such a page by writing a static prototype of the HTML page. 様々なコンテントを生成するブログラム コードによりテーブルとその他の可変部分を次々と置き換えることができます。You could then replace the table and other variable parts with program code that generates the content that varies from one occasion to the next.

アプリケーションでテンプレートを使用することにより、例えば、長い一連のステートメントを記述するよりも、出力の最終形式をみて容易に作成することができます。Using a template in your application makes it is easier to see the final form of the output than you could in, for example, a long series of write statements. 出力の形式を変更が、簡単かつ確実になります。Making changes to the form of the output is easier and more reliable.

任意のアプリケーションでの ランタイム テキスト テンプレートの作成Creating a Run-Time Text Template in any Application

ランタイム テキスト テンプレートを作成するにはTo create a run-time text template

  1. ソリューション エクスプローラーで、プロジェクトのショートカット メニューの 追加 > 新しい項目の追加 を選択します。In Solution Explorer, on the shortcut menu of your project, choose Add > New Item.

  2. 新しい項目の追加 ダイアログ ボックスで、ランタイム テキスト テンプレート を選択します。In the Add New Item dialog box, select Runtime Text Template. (Visual Basic では、一般的な項目 > 全般)。(In Visual Basic look under Common Items > General.)

  3. テンプレートファイルの名前を入力します。Type a name for your template file.

    Note

    テンプレートファイル名は、生成されたコードでクラス名として使用されます。The template file name will be used as a class name in the generated code. そのため、スペースまたは句読点を含めることはできません。Therefore, it should not have spaces or punctuation.

  4. [追加] をクリックします。Choose Add.

    拡張子 .tt を持つ新しいファイルが作成されます。A new file is created that has extension .tt. その カスタム ツール プロパティには TextTemplatingFilePreprocessor が設定されています。Its Custom Tool property is set to TextTemplatingFilePreprocessor. 次の行が含まれています。It contains the following lines:

    <#@ template language="C#" #>
    <#@ assembly name="System.Core" #>
    <#@ import namespace="System.Linq" #>
    <#@ import namespace="System.Text" #>
    <#@ import namespace="System.Collections.Generic" #>
    

既存のファイルのランタイム テンプレートへの変換Converting an Existing File to a Run-Time Template

テンプレートを作成する優れた方法は、既存の出力の例を変換することです。A good way to create a template is to convert an existing example of the output. たとえば、アプリケーションが HTML ファイルを生成する場合ならば、プレーンな HTML ファイルの作成から開始します。For example, if your application will generate HTML files, you can start by creating a plain HTML file. 正しく動作しいて、その外観が正しいことを確認してください。Make sure that it works correctly and that its appearance is correct. その後、Visual Studio プロジェクトに含め、テンプレートに変換します。Then include it into your Visual Studio project and convert it to a template.

既存のテキスト ファイルをランタイム テンプレートに変換するにはTo convert an existing text file to a run-time template

  1. ファイルを Visual Studio プロジェクトに含めます。Include the file into your Visual Studio project. ソリューション エクスプ ローラーで、プロジェクトのショートカット メニューの 追加 > 既存の項目 を選択します。In Solution Explorer, on the shortcut menu of the project, choose Add > Existing Item.

  2. ファイルの設定 カスタム ツール プロパティを TextTemplatingFilePreprocessor にします。Set the file's Custom Tools property to TextTemplatingFilePreprocessor. ソリューション エクスプ ローラーで、ファイルのショートカット メニューの プロパティ を選択します。In Solution Explorer, on the shortcut menu of the file, choose Properties.

    Note

    プロパティが既に設定されている場合は、TextTemplatingFilePreprocessor ではなく TextTemplatingFileGenerator であることを確認します。If the property is already set, make sure that it is TextTemplatingFilePreprocessor and not TextTemplatingFileGenerator. 拡張子 .tt のファイルをインクルードする場合に起こりえます。This can happen if you include a file that already has the extension .tt.

  3. ファイル名の拡張子を .tt に変更します。Change the file name extension to .tt. この手順は省略可能ですが、不適切なエディターでファイルを開いてしまうことを防ぎます。Although this step is optional, it helps you avoid opening the file in an incorrect editor.

  4. ファイル名のメイン部分から、スペースまたは句読点を削除します。Remove any spaces or punctuation from the main part of the file name. たとえば"My Web Page.tt"は適切ではないですが、"MyWebPage.tt"は適切です。For example "My Web Page.tt" would be incorrect, but "MyWebPage.tt" is correct. ファイル名は、生成されたコードでクラス名として使用されます。The file name will be used as a class name in the generated code.

  5. ファイルの先頭に次の行を挿入します。Insert the following line at the beginning of the file. Visual Basic プロジェクトで作業している場合は、"C#" が "VB" に置き換えられます。If you are working in a Visual Basic project, replace "C#" with "VB".

    <#@ template language="C#" #>

ランタイム テンプレートの内容The Content of the Run-Time Template

テンプレートディレクティブTemplate directive

ファイルが作成された時のように、テンプレートの最初の行は次のようにしてください。Keep the first line of the template as it was when you created the file:

<#@ template language="C#" #>

language パラメーターは、プロジェクトの言語によって異なります。The language parameter will depend on the language of your project.

プレーン コンテンツPlain content

アプリケーションが生成したいテキストを含む .tt ファイルを編集します。Edit the .tt file to contain the text that you want your application to generate. 例:For example:

<html><body>
<h1>Sales for January</h2>
<!-- table to be inserted here -->
This report is Company Confidential.
</body></html>

埋め込みプログラムコードEmbedded program code

プログラム コードは<##>の間に挿入します。You can insert program code between <# and #>. 例:For example:

<table>
    <# for (int i = 1; i <= 10; i++)
       { #>
         <tr><td>Test name <#= i #> </td>
             <td>Test value <#= i * i #> </td> </tr>
    <# } #>
 </table>
<table>
<#
    For i As Integer = 1 To 10
#>
    <tr><td>Test name <#= i #> </td>
      <td>Test value <#= i*i #> </td></tr>
<#
    Next
#>
</table>

ステートメントは、<# ... #>の間に挿入され、式は<#= ... #>の間に挿入されていることにことに注意してください。Notice that statements are inserted between <# ... #> and expressions are inserted between <#= ... #>. 詳細については、「T4 テキスト テンプレートの作成」を参照してください。For more information, see Writing a T4 Text Template.

テンプレートの使用Using the Template

テンプレートから作成されたコードThe code built from the template

保存すると、 .tt ファイルの子に .cs または .vb ファイルが生成されています。When you save the .tt file, a subsidiary .cs or .vb file is generated. ソリューション エクスプ ローラー でこのファイルを確認するには、 .tt ファイル ノードを展開します。To see this file in Solution Explorer, expand the .tt file node. Visual Basic プロジェクトでは、ソリューション エクスプローラー ツールバーの すべてのファイル をまず選択します。In a Visual Basic project, first choose Show All Files in the Solution Explorer toolbar.

子ファイルには、TransformText()というメソッドを含む部分クラスが含まれています。Notice that the subsidiary file contains a partial class that contains a method called TransformText(). このメソッドは、アプリケーションから呼び出すことができます。You can call this method from your application.

実行時のテキストの生成Generating text at run time

アプリケーションコードでは、次のような呼び出しを使用して、テンプレートのコンテンツを生成できます。In your application code, you can generate the content of your template using a call like this:

MyWebPage page = new MyWebPage();
String pageContent = page.TransformText();
System.IO.File.WriteAllText("outputPage.html", pageContent);
Dim page = New My.Templates.MyWebPage
Dim pageContent = page.TransformText()
System.IO.File.WriteAllText("outputPage.html", pageContent)

生成されるクラスを特定の名前空間に配置するには、テキスト テンプレート ファイルの カスタム ツールの Namespace プロパティを設定します。To place the generated class in a particular namespace, set the Custom Tool Namespace property of the text template file.

ランタイムテキストテンプレートのデバッグDebugging Runtime Text Templates

通常のコードと同じ方法でランタイム テキスト テンプレートをデバッグしテストします。Debug and test runtime text templates in the same way as ordinary code.

テキストテンプレートにブレークポイントを設定できます。You can set a breakpoint in a text template. Visual Studio からデバッグモードでアプリケーションを起動する場合は、通常の方法でコードをステップ実行し、ウォッチ式を評価できます。If you start the application in debugging mode from Visual Studio, you can step through the code and evaluate watch expressions in the usual way.

コンストラクターでのパラメーターの引き渡しPassing parameters in the constructor

通常、テンプレートでは、アプリケーションの他の部分からデータをインポートする必要があります。Usually a template must import some data from other parts of the application. これを簡単にするために、テンプレートによって作成されるコードは、部分クラスになっています。To make this easy, the code built by the template is a partial class. プロジェクトの別のファイルで、同じクラスの別の部分を作成できます。You can create another part of the same class in another file in your project. そのファイルには、パラメーター、プロパティ、およびテンプレートでは、埋め込まれているコードと、アプリケーションの残りの部分の両方にアクセスできる機能を持つコンストラクターを含めることができます。That file can include a constructor with parameters, properties and functions that can be accessed both by the code that is embedded in the template, and by the rest of the application.

たとえば、MyWebPageCode.cs という別のファイルを作成し、For example, you could create a separate file MyWebPageCode.cs:

partial class MyWebPage
{
    private MyData m_data;
    public MyWebPage(MyData data) { this.m_data = data; }}

MyWebPage.tt というテンプレート ファイルで次のように記述し、In your template file MyWebPage.tt, you could write:

<h2>Sales figures</h2>
<table>
<# foreach (MyDataItem item in m_data.Items)
   // m_data is declared in MyWebPageCode.cs
   { #>
      <tr><td> <#= item.Name #> </td>
          <td> <#= item.Value #> </td></tr>
<# } // end of foreach
#>
</table>

アプリケーションでこのテンプレートを使用するには、次のようにします。To use this template in the application:

MyData data = ...;
MyWebPage page = new MyWebPage(data);
String pageContent = page.TransformText();
System.IO.File.WriteAllText("outputPage.html", pageContent);

Visual Basic でのコンストラクターのパラメーターConstructor parameters in Visual Basic

Visual Basic では、次の内容を含んだ MyWebPageCode.vb という別のファイルに、In Visual Basic, the separate file MyWebPageCode.vb contains:

Namespace My.Templates
  Partial Public Class MyWebPage
    Private m_data As MyData
    Public Sub New(ByVal data As MyData)
      m_data = data
    End Sub
  End Class
End Namespace

テンプレート ファイルには次の内容を記述し、The template file could contain:

<#@ template language="VB" #>
<html><body>
<h1>Sales for January</h2>
<table>
<#
    For Each item In m_data.Items
#>
    <tr><td>Test name <#= item.Name #> </td>
      <td>Test value <#= item.Value #> </td></tr>
<#
    Next
#>
</table>
This report is Company Confidential.
</body></html>

テンプレートは、コンストラクターでパラメーターを渡すことによって呼び出すことができます。The template can invoked by passing the parameter in the constructor:

Dim data = New My.Templates.MyData
    ' Add data values here ....
Dim page = New My.Templates.MyWebPage(data)
Dim pageContent = page.TransformText()
System.IO.File.WriteAllText("outputPage.html", pageContent)

テンプレートプロパティでデータを渡すPassing data in template properties

テンプレートにデータを渡す別の方法として、部分クラス定義でテンプレートクラスにパブリックプロパティを追加する方法があります。An alternative way of passing data to the template is to add public properties to the template class in a partial class definition. TransformText() を呼び出す前に、アプリケーションでプロパティを設定します。Your application can set the properties before invoking TransformText().

また、部分定義でテンプレートクラスにフィールドを追加することもできます。You can also add fields to your template class in a partial definition. これにより、テンプレートの実行の間に連続的にデータを渡すことができます。This enables you to pass data between successive executions of the template.

部分クラスを使用するコードUse partial classes for code

多くの開発者は、テンプレート内で大量のコードを作成することを回避することを好みます。Many developers prefer to avoid writing large bodies of code in templates. そのようにせず、テンプレート ファイルと同じ名前を持つ部分クラスでメソッドを定義することができます。Instead, you can define methods in a partial class that has the same name as the template file. これらのメソッドをテンプレートから呼び出します。Call those methods from the template. このようにすると、テンプレートはよりターゲットの出力の文字列とおなじようになり、より明確になります。In this way, the template shows more clearly what the target output string will look like. 結果の外観に関する議論を、表示するデータを作成するロジックから分離できます。Discussions about the appearance of the result can be separated from the logic of creating the data that it displays.

アセンブリと参照Assemblies and references

テンプレート コードで、System.Xml.dll といった .NET またはその他のアセンブリを参照したい場合には、通常と同じように、プロジェクトの参照で追加します。If you want your template code to reference a .NET or other assembly such as System.Xml.dll, add it to your project's References in the usual manner.

usingステートメントといった方法で名前空間をインポートする場合は、importディレクティブで行います。If you want to import a namespace in the same way as a using statement, you can do this with the import directive:

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

これらのディレクティブは、<#@templateディレクティブ直後のファイルの先頭に配置する必要があります。These directives must be placed at the beginning of the file, immediately after the <#@template directive.

共有コンテンツShared content

複数のテンプレート間で共有されるテキストがある場合は、それを別のファイルに配置し、表示される各ファイルに含めることができます。If you have text that is shared between several templates, you can place it in a separate file and include it in each file in which it should appear:

<#@include file="CommonHeader.txt" #>

含まれるコンテンツは、プログラム コードやプレーン テキストでのあらゆる組み合わせを含めることができ、それには、その他の include ディレクティブおよび他のディレクティブを含ませることができます。The included content can contain any mixture of program code and plain text, and it can contain other include directives and other directives.

include ディレクティブは、テンプレート ファイルまたはインクルード ファイルのテキスト内の任意の場所で使用できます。The include directive can be used anywhere within the text of a template file or an included file.

ランタイム テキスト テンプレート間の継承Inheritance between Run-Time Text Templates

抽象クラスになりうる基底クラス テンプレートを記述することで、実行時テンプレート間でコンテンツを共有することができます。You can share content between run-time templates by writing a base class template, which can be abstract. <@#template#> ディレクティブの inherits パラメーターを使用して、別のランタイム テンプレート クラスを参照します。Use the inherits parameter of the <@#template#> directive to reference another runtime template class.

継承パターン: 基底メソッドのフラグメントInheritance pattern: Fragments in Base Methods

次の例で使用しているパターンでは、次の点に注意してください。In the pattern used in the example that follows, notice the following points:

  • 基底クラスSharedFragmentsは、クラス機能ブロック<#+ ... #>内でメソッドを定義します。The base class SharedFragments defines methods within class feature blocks <#+ ... #>.

  • 基底クラスには、フリー テキストは含まれません。The base class contains no free text. 代わりに、すべてのテキスト ブロックは、クラス機能メソッド内で発生します。Instead, all of its text blocks occur inside the class feature methods.

  • 派生クラスは、SharedFragmentsで定義されているメソッドを呼び出します。The derived class invokes the methods defined in SharedFragments.

  • アプリケーションは、派生クラスの TextTransform() メソッドを呼び出します。基底クラスSharedFragmentsを変換しません。The application calls the TextTransform() method of the derived class, but does not transform the base class SharedFragments.

  • 基底と派生クラスの両方がランタイム テキスト テンプレートです。つまり、カスタム ツールプロパティは、TextTemplatingFilePreprocessor に設定します。Both the base and derived classes are runtime text templates; that is, the Custom Tool property is set to TextTemplatingFilePreprocessor.

SharedFragments.tt:SharedFragments.tt:

<#@ template language="C#" #>
<#+
protected void SharedText(int n)
{
#>
   Shared Text <#= n #>
<#+
}
// Insert more methods here if required.
#>

MyTextTemplate1.tt:MyTextTemplate1.tt:

<#@ template language="C#" inherits="SharedFragments" #>
begin 1
   <# SharedText(2); #>
end 1

MyProgram.cs:MyProgram.cs:

...
MyTextTemplate1 t1  = new MyTextTemplate1();
string result = t1.TransformText();
Console.WriteLine(result);

結果の出力は次のようになります。The resulting output:

begin 1
    Shared Text 2
end 1

継承パターン: 基底本体内のテキストInheritance Pattern: Text in Base Body

テンプレートの継承を使用する別の方法は、基底テンプレートの中で大きなテキスト定義することです。In this alternative approach to using template inheritance, the bulk of the text is defined in the base template. 派生テンプレートは、ベースのコンテンツに適合したデータと テキスト フラグメントを提供します。The derived templates provide data and text fragments that fit into the base content.

AbstractBaseTemplate1.tt:AbstractBaseTemplate1.tt:

<#@ template language="C#" #>

Here is the description for this derived template:
  <#= this.Description #>

Here is the fragment specific to this derived template:
<#
  this.PushIndent("  ");
  SpecificFragment(42);
  this.PopIndent();
#>
End of common template.
<#+
  // State set by derived class before calling TextTransform:
  protected string Description = "";
  // 'abstract' method to be defined in derived classes:
  protected virtual void SpecificFragment(int n) { }
#>

DerivedTemplate1.tt:DerivedTemplate1.tt:

<#@ template language="C#" inherits="AbstractBaseTemplate1" #>
<#
  // Set the base template properties:
  base.Description = "Description for this derived class";

  // Run the base template:
  base.TransformText();

#>
End material for DerivedTemplate1.

<#+
// Provide a fragment specific to this derived template:

protected override void SpecificFragment(int n)
{
#>
   Specific to DerivedTemplate1 : <#= n #>
<#+
}
#>

アプリケーションコード:Application code:

...
DerivedTemplate1 t1 = new DerivedTemplate1();
string result = t1.TransformText();
Console.WriteLine(result);

結果の出力:Resulting output:

Here is the description for this derived template:
  Description for this derived class

Here is the fragment specific to this derived template:
     Specific to DerivedTemplate1 : 42
End of common template.
End material for DerivedTemplate1.

デザイン時テンプレート: アプリケーションの一部になるコードを生成するテンプレートを使用する場合は次を参照してください。T4 テキスト テンプレートを使用したデザイン時コード生成Design-time templates: If you want to use a template to generate code that becomes part of your application, see Design-Time Code Generation by using T4 Text Templates.

ランタイム テンプレートは、コンパイル時にテンプレートおよびその内容を決定し、任意のアプリケーションで使用できます。Run-time templates can be used in any application where the templates and their content are determined at compile time. 実行時に変更される、テンプレートからテキストを生成する Visual Studio 拡張機能を作成したい場合は、次を参照してください。 VS 拡張機能でテキスト変換を呼び出すBut if you want to write a Visual Studio extension that generates text from templates that change at run time, see Invoking Text Transformation in a VS Extension.

関連項目See also