Génération de texte durant l'exécution à l'aide des modèles de texte T4Run-Time Text Generation with T4 Text Templates

Vous pouvez générer des chaînes de texte dans votre application en cours d’exécution à l’aide de modèles de texte de runtime de Visual Studio.You can generate text strings in your application at run time by using Visual Studio runtime text templates. L’ordinateur où s’exécute l’application n’a pas pour que Visual Studio.The computer where the application executes does not have to have Visual Studio. Modèles de runtime sont parfois appelés « modèles de texte prétraités », car au moment de la compilation, le modèle génère du code qui est exécuté au moment de l’exécution.Runtime templates are sometimes called "preprocessed text templates" because at compile time, the template generates code that is executed at run time.

Chaque modèle est un mélange de texte tel qu’il apparaîtra dans la chaîne générée et des fragments de code de programme.Each template is a mixture of the text as it will appear in the generated string, and fragments of program code. Les fragments de programme fournissent des valeurs pour les parties variables de la chaîne et également de contrôler les parties conditionnelles et répétées.The program fragments supply values for the variable parts of the string, and also control conditional and repeated parts.

Par exemple, le modèle suivant peut être utilisé dans une application qui crée un rapport 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>

Notez que le modèle est une page HTML dans lequel les parties variables ont été remplacés par du code de programme.Notice that the template is an HTML page in which the variable parts have been replaced with program code. Vous pouvez commencer la conception d’une telle page en écrivant un prototype statique de la page HTML.You could begin the design of such a page by writing a static prototype of the HTML page. Vous pouvez ensuite remplacer la table et les autres parties variables avec du code de programme qui génère le contenu varie d’un cas à l’autre.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.

À l’aide d’un modèle dans votre application, il est plus facile de déterminer la forme finale de la sortie que vous pourriez le faire dans, par exemple, une longue série d’instructions d’écriture.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. Apporter des modifications à la forme de la sortie est plus facile et plus fiable.Making changes to the form of the output is easier and more reliable.

Création d’un modèle de texte d’exécution dans n’importe quelle ApplicationCreating a Run-Time Text Template in any Application

Pour créer un modèle de texte d’exécutionTo create a run-time text template

  1. Dans l’Explorateur de solutions, dans le menu contextuel de votre projet, choisissez ajouter > un nouvel élément.In Solution Explorer, on the shortcut menu of your project, choose Add > New Item.

  2. Dans le ajouter un nouvel élément boîte de dialogue, sélectionnez modèle de texte Runtime.In the Add New Item dialog box, select Runtime Text Template. (En Visual Basic, regardez sous éléments communs > général.)(In Visual Basic look under Common Items > General.)

  3. Tapez un nom pour votre fichier de modèle.Type a name for your template file.

    Note

    Le nom du fichier modèle sera utilisé comme nom de classe dans le code généré.The template file name will be used as a class name in the generated code. Par conséquent, il ne doit pas avoir d’espaces ni ponctuation.Therefore, it should not have spaces or punctuation.

  4. Sélectionnez Ajouter.Choose Add.

    Un nouveau fichier est créé qui a l’extension .tt.A new file is created that has extension .tt. Son un outil personnalisé propriété est définie sur TextTemplatingFilePreprocessor.Its Custom Tool property is set to TextTemplatingFilePreprocessor. Il contient les lignes suivantes :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" #>
    

Conversion d’un fichier existant à un modèle au moment de l’exécutionConverting an Existing File to a Run-Time Template

Un bon moyen pour créer un modèle consiste à convertir un exemple existant de la sortie.A good way to create a template is to convert an existing example of the output. Par exemple, si votre application doit générer des fichiers HTML, vous pouvez démarrer en créant un fichier HTML standard.For example, if your application will generate HTML files, you can start by creating a plain HTML file. Assurez-vous qu’elle fonctionne correctement et que son apparence est correct.Make sure that it works correctly and that its appearance is correct. Puis l’inclure dans votre projet Visual Studio et la convertir en un modèle.Then include it into your Visual Studio project and convert it to a template.

Pour convertir un fichier texte existant à un modèle au moment de l’exécutionTo convert an existing text file to a run-time template

  1. Insérez le fichier dans votre projet Visual Studio.Include the file into your Visual Studio project. Dans l’Explorateur de solutions, dans le menu contextuel du projet, choisissez ajouter > élément existant.In Solution Explorer, on the shortcut menu of the project, choose Add > Existing Item.

  2. Définir le fichier outils personnalisés propriété TextTemplatingFilePreprocessor.Set the file's Custom Tools property to TextTemplatingFilePreprocessor. Dans l’Explorateur de solutions, dans le menu contextuel du fichier, choisissez propriétés.In Solution Explorer, on the shortcut menu of the file, choose Properties.

    Note

    Si la propriété est déjà définie, assurez-vous qu’il s’agit TextTemplatingFilePreprocessor et non TextTemplatingFileGenerator.If the property is already set, make sure that it is TextTemplatingFilePreprocessor and not TextTemplatingFileGenerator. Cela peut se produire si vous incluez un fichier qui comporte déjà l’extension .tt.This can happen if you include a file that already has the extension .tt.

  3. Modifier l’extension de nom de fichier .tt.Change the file name extension to .tt. Bien que cette étape est facultative, il vous permet d’éviter l’ouverture du fichier dans un éditeur incorrect.Although this step is optional, it helps you avoid opening the file in an incorrect editor.

  4. Supprimer les espaces ou la ponctuation de la partie principale du nom de fichier.Remove any spaces or punctuation from the main part of the file name. Par exemple « My Web Page.tt » est incorrect, mais « MyWebPage.tt » est correct.For example "My Web Page.tt" would be incorrect, but "MyWebPage.tt" is correct. Le nom de fichier sera utilisé comme nom de classe dans le code généré.The file name will be used as a class name in the generated code.

  5. Insérez la ligne suivante au début du fichier.Insert the following line at the beginning of the file. Si vous travaillez dans un projet Visual Basic, remplacez « C# » avec « VB ».If you are working in a Visual Basic project, replace "C#" with "VB".

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

Le contenu du modèle d’exécutionThe Content of the Run-Time Template

Directive de modèleTemplate directive

Conserver la première ligne du modèle tel qu’il était lorsque vous avez créé le fichier :Keep the first line of the template as it was when you created the file:

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

Le paramètre de langue dépend de la langue de votre projet.The language parameter will depend on the language of your project.

Contenu simplePlain content

Modifier le .tt fichier contient le texte que vous souhaitez générer votre application.Edit the .tt file to contain the text that you want your application to generate. Exemple :For example:

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

Code de programme incorporéEmbedded program code

Vous pouvez insérer du code de programme entre <# et #>.You can insert program code between <# and #>. Exemple :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>

Notez que les instructions sont insérées entre <# ... #> et les expressions sont insérées entre <#= ... #>.Notice that statements are inserted between <# ... #> and expressions are inserted between <#= ... #>. Pour plus d’informations, consultez écriture d’un modèle de texte T4.For more information, see Writing a T4 Text Template.

Utilisation du modèleUsing the Template

Le code généré à partir du modèleThe code built from the template

Lorsque vous enregistrez le .tt de fichiers, une filiale .cs ou .vb fichier est généré.When you save the .tt file, a subsidiary .cs or .vb file is generated. Pour afficher ce fichier dans l’Explorateur de solutions, développez le .tt nœud de fichier.To see this file in Solution Explorer, expand the .tt file node. Dans un projet Visual Basic, choisissez d’abord afficher tous les fichiers dans le l’Explorateur de solutions barre d’outils.In a Visual Basic project, first choose Show All Files in the Solution Explorer toolbar.

Notez que le fichier auxiliaire contient une classe partielle qui contient une méthode appelée TransformText().Notice that the subsidiary file contains a partial class that contains a method called TransformText(). Vous pouvez appeler cette méthode à partir de votre application.You can call this method from your application.

Génération de texte au moment de l’exécutionGenerating text at run time

Dans le code de votre application, vous pouvez générer le contenu de votre modèle à l’aide d’un appel à ceci :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)

Pour placer la classe générée dans un espace de noms particulier, définissez le Namespace d’outil personnalisé propriété du fichier de modèle de texte.To place the generated class in a particular namespace, set the Custom Tool Namespace property of the text template file.

Débogage des modèles de texte d’exécutionDebugging Runtime Text Templates

Déboguer et tester des modèles de texte d’exécution de la même façon en tant que code ordinaire.Debug and test runtime text templates in the same way as ordinary code.

Vous pouvez définir un point d’arrêt dans un modèle de texte.You can set a breakpoint in a text template. Si vous démarrez l’application en mode débogage à partir de Visual Studio, vous pouvez parcourir le code et évaluer des expressions de surveillance à l’accoutumée.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.

Passage de paramètres dans le constructeurPassing parameters in the constructor

Généralement un modèle doit importer des données à partir d’autres parties de l’application.Usually a template must import some data from other parts of the application. Pour faciliter la tâche, le code généré par le modèle est une classe partielle.To make this easy, the code built by the template is a partial class. Vous pouvez créer une autre partie de la même classe dans un autre fichier dans votre projet.You can create another part of the same class in another file in your project. Ce fichier peut inclure un constructeur avec des paramètres, des propriétés et des fonctions qui sont accessibles par le code qui est incorporé dans le modèle et par le reste de l’application.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.

Par exemple, vous pouvez créer un fichier distinct 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; }}

Dans votre fichier de modèle MyWebPage.tt, vous pouvez écrire :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>

Pour utiliser ce modèle dans l’application :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);

Paramètres du constructeur en Visual BasicConstructor parameters in Visual Basic

En Visual Basic, le fichier distinct MyWebPageCode.vb contient :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

Le fichier de modèle peut contenir :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>

Le modèle peut être appelé en transmettant le paramètre dans le constructeur :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)

Passage de données dans les propriétés du modèlePassing data in template properties

Une autre façon de passer des données au modèle consiste à ajouter des propriétés publiques à la classe de modèle dans une définition de classe partielle.An alternative way of passing data to the template is to add public properties to the template class in a partial class definition. Votre application peut définir les propriétés avant d’appeler TransformText().Your application can set the properties before invoking TransformText().

Vous pouvez également ajouter des champs à votre classe de modèle dans une définition partielle.You can also add fields to your template class in a partial definition. Cela vous permet de passer des données entre des exécutions consécutives du modèle.This enables you to pass data between successive executions of the template.

Utilisez des classes partielles pour le codeUse partial classes for code

De nombreux développeurs préfèrent éviter d’écrire le corps de code volumineux dans les modèles.Many developers prefer to avoid writing large bodies of code in templates. Au lieu de cela, vous pouvez définir des méthodes dans une classe partielle qui porte le même nom que le fichier de modèle.Instead, you can define methods in a partial class that has the same name as the template file. Appelez ces méthodes à partir du modèle.Call those methods from the template. De cette façon, le modèle de montre plus clairement la chaîne de sortie cible ressemblera.In this way, the template shows more clearly what the target output string will look like. Discussions sur l’apparence du résultat peuvent être séparées de la logique de création des données qu’il affiche.Discussions about the appearance of the result can be separated from the logic of creating the data that it displays.

Assemblys et référencesAssemblies and references

Si vous souhaitez que votre code de modèle pour référencer un .NET ou autre assembly tel que System.Xml.dll, ajoutez-le à votre projet références comme d’habitude.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.

Si vous souhaitez importer un espace de noms dans la même façon qu’un using instruction, vous pouvez le faire avec la import directive :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" #>

Ces directives doivent être placées au début du fichier, immédiatement après la <#@template directive.These directives must be placed at the beginning of the file, immediately after the <#@template directive.

Contenu partagéShared content

Si vous avez du texte qui est partagé entre plusieurs modèles, vous pouvez placer dans un fichier distinct et l’inclure dans chaque fichier dans lequel il doit apparaître :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" #>

Le contenu inclus peut contenir toute combinaison de code de programme et de texte brut, et il peut contenir d’autres directives include et autres directives.The included content can contain any mixture of program code and plain text, and it can contain other include directives and other directives.

La directive include peut être utilisée n’importe où dans le texte d’un fichier de modèle ou un fichier inclus.The include directive can be used anywhere within the text of a template file or an included file.

Héritage entre les modèles de texte de l’exécutionInheritance between Run-Time Text Templates

Vous pouvez partager du contenu entre les modèles au moment de l’exécution en écrivant un modèle de classe de base, qui peut être abstract.You can share content between run-time templates by writing a base class template, which can be abstract. Utilisez le inherits paramètre de la <@#template#> directive pour référencer une autre classe de modèle de runtime.Use the inherits parameter of the <@#template#> directive to reference another runtime template class.

Modèle d’héritage : Fragments dans les méthodes de BaseInheritance pattern: Fragments in Base Methods

Dans le modèle utilisé dans l’exemple suivant, notez les points suivants :In the pattern used in the example that follows, notice the following points:

  • La classe de base SharedFragments définit des méthodes dans les blocs de fonctionnalité de classe <#+ ... #>.The base class SharedFragments defines methods within class feature blocks <#+ ... #>.

  • La classe de base ne contient aucun texte libre.The base class contains no free text. Au lieu de cela, tous ses blocs de texte se produisent à l’intérieur des méthodes de la fonctionnalité de classe.Instead, all of its text blocks occur inside the class feature methods.

  • La classe dérivée appelle les méthodes définies dans SharedFragments.The derived class invokes the methods defined in SharedFragments.

  • L’application appelle le TextTransform() méthode de la classe dérivée, mais ne transforme ne pas la classe de base SharedFragments.The application calls the TextTransform() method of the derived class, but does not transform the base class SharedFragments.

  • Les classes de base et dérivées sont des modèles de texte du runtime ; Autrement dit, le un outil personnalisé propriété est définie sur 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);

Le résultat obtenu :The resulting output:

begin 1
    Shared Text 2
end 1

Modèle d’héritage : Texte dans le corps de BaseInheritance Pattern: Text in Base Body

Dans cette approche alternative à l’aide de l’héritage de modèle, la majeure partie du texte est définie dans le modèle de base.In this alternative approach to using template inheritance, the bulk of the text is defined in the base template. Les modèles dérivés fournissent des données et les fragments de texte qui s’intègrent pas le contenu de base.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 #>
<#+
}
#>

Code d’application :Application code:

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

Sortie obtenue :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.

Les modèles au moment du design : Si vous souhaitez utiliser un modèle pour générer du code qui devient partie intégrante de votre application, consultez génération de Code au moment du Design à l’aide de modèles de texte 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.

Modèles de l’exécution peuvent être utilisés dans n’importe quelle application où les modèles et leur contenu sont déterminés au moment de la compilation.Run-time templates can be used in any application where the templates and their content are determined at compile time. Toutefois, si vous souhaitez écrire une extension Visual Studio qui génère du texte à partir de modèles qui changent au moment de l’exécution, consultez appel d’une Transformation de texte dans une Extension 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.

Voir aussiSee also