Génération de code durant la conception à l'aide de modèles de texte T4

Les modèles de texte T4 au moment du design vous permettent de générer du code de programme et d'autres fichiers dans votre projet Visual Studio. En général, vous écrivez les modèles afin qu'ils fassent varier le code qu'ils génèrent d'après les données d'un modèle. Un modèle est un fichier ou une base de données qui contient des informations clés à propos des spécifications de votre application.

Par exemple, vous pouvez avoir un modèle qui définit un flux de travail, en tant que table ou diagramme. À partir du modèle, vous pouvez générer le logiciel qui exécute le flux de travail. Lorsque les spécifications des utilisateurs changent, il est facile de discuter du nouveau flux de travail avec les utilisateurs. La régénération du code à partir du flux de travail est plus fiable que la mise à jour manuelle du code.

Notes

Un modèle est une source de données qui décrit un aspect particulier d'une application. Il peut se présenter sous n'importe quelle forme, dans tout type de fichier ou de base de données. Il n'est pas nécessaire qu'il se présente sous une forme spécifique, telle qu'un modèle UML ou un modèle de langage spécifique à un domaine. Les modèles classiques se présentent sous la forme de tables ou de fichiers XML.

Vous êtes probablement déjà familiarisé avec la génération de code. Lorsque vous définissez des ressources dans un fichier .resx de votre solution Visual Studio, un ensemble de classes et de méthodes est automatiquement généré. Le fichier de ressources vous permet de modifier les ressources beaucoup plus facilement et de manière plus fiable que si vous deviez modifier les classes et les méthodes. Avec les modèles de texte, vous pouvez générer du code de la même manière à partir d'une source de votre propre conception.

Un modèle de texte contient un mélange de texte que vous souhaitez générer et de code du programme qui génère des parties variables du texte. Le code du programme vous permet de répéter ou d'omettre de manière conditionnelle des parties du texte généré. Le texte généré peut être du code du programme qui fera partie de votre application.

Création d'un modèle de texte T4 au moment du design

Pour créer un modèle T4 au moment du design dans Visual Studio

  1. Créez un projet Visual Studio ou ouvrez un projet existant.

    Par exemple, dans le menu Fichier, pointez sur Nouveau, puis cliquez sur Projet.

  2. Ajoutez un fichier modèle de texte à votre projet et nommez-le NouveauModèle.tt.

    Pour ce faire, dans l'Explorateur de solutions, cliquez avec le bouton droit sur votre projet et pointez sur Ajouter, puis cliquez sur Nouvel élément. Dans la boîte de dialogue Ajouter un nouvel élément, sélectionnez Modèle de texte dans le volet Modèles. Nommez le fichier NouveauModèle.tt.

    Notez que la propriété Outil personnalisé du fichier est TextTemplatingFileGenerator.

  3. Ouvrez le fichier. Il contient déjà les directives suivantes :

    <#@ template debug="false" hostspecific="false" language="C#" #>
    <#@ output extension=".txt" #>
    

    Si vous avez ajouté le modèle à un projet Visual Basic, l'attribut de langage sera "VB".

  4. Ajoutez du texte à la fin du fichier. Par exemple :

    Hello, world!
    
  5. Enregistrez le fichier.

    Une boîte de message Avertissement de sécurité peut s'afficher, vous demandant de confirmer que vous voulez exécuter le modèle. Cliquez sur OK.

  6. Dans l'Explorateur de solutions, développez le nœud NouveauModèle.tt afin de trouver un fichier nommé NouveauModèle.txt. Ce fichier contient le texte que vous avez entré.

    Notes

    Si vous avez créé un projet Visual Basic, vous devez cliquer sur Afficher tous les fichiers pour afficher le fichier de sortie NouveauModèle.txt.

Régénération du code

Un modèle sera exécuté, générant le fichier auxiliaire, dans les cas suivants :

  • Vous modifiez un modèle, puis déplacez le focus vers une autre fenêtre Visual Studio.

  • Vous enregistrez le modèle.

  • Vous cliquez sur Transformer tous les modèles dans la barre d'outils de l'Explorateur de solutions. Vous transformez ainsi tous les modèles de la solution Visual Studio.

  • Vous cliquez avec le bouton droit sur un ou plusieurs fichiers dans l'Explorateur de solutions, puis cliquez sur Exécuter un outil personnalisé. Utilisez cette méthode pour transformer un ensemble sélectionné de modèles.

Vous pouvez également configurer un projet Visual Studio pour que les modèles soient exécutés lorsque les fichiers de données qu'ils lisent ont été modifiés. Pour plus d'informations, consultez Régénération automatique du code.

Génération du texte variable

Les modèles de texte vous permettent d'utiliser du code de programme pour faire varier le contenu du fichier généré.

Pour générer du texte à l'aide du code de programme

  1. Modifiez le contenu du fichier .tt :

    <#@ template debug="false" hostspecific="false" language="C#" #>
    <#@ output extension=".txt" #>
    <#int top = 10;
    
    for (int i = 0; i<=top; i++) { #>
    The square of <#= i #> is <#= i*i #>
    <# } #>
    
    <#@ template debug="false" hostspecific="false" language="VB" #>
    <#@ output extension=".txt" #>
    <#Dim top As Integer = 10
    
    For i As Integer = 0 To top
    #>
        The square of <#= i #> is <#= i*i #>
    <#
    Next
    #>
    
  2. Enregistrez le fichier .tt et inspectez une nouvelle fois le fichier .txt généré. Il répertorie les carrés des nombres de 0 à 9.

Notez que les instructions sont placées dans <#...#> et que les expressions uniques sont placées dans <#=...#>. Pour plus d'informations, consultez Écriture d'un modèle de texte T4.

Si vous écrivez le code de génération dans Visual Basic, la directive template doit contenir language="VB". "C#" est la valeur par défaut.

Génération de code ou de ressources pour votre solution

Vous pouvez générer des fichiers programme qui varient en fonction d'un modèle. Un modèle est une entrée telle qu'une base de données, un fichier de configuration, un modèle UML, un modèle DSL ou une autre source. Vous générez habituellement plusieurs fichiers programme à partir du même modèle. Pour ce faire, vous créez un fichier modèle (template) pour chaque fichier programme généré et faites en sorte que tous les modèles (templates) lisent le même modèle (model).

Pour générer du code de programme ou des ressources

  1. Modifiez la directive de sortie pour générer un fichier du type approprié, tel que .cs, .vb, .resx ou .xml.

  2. Insérez le code qui générera le code de solution dont vous avez besoin. Par exemple, si vous voulez générer trois déclarations de champs de nombres entiers dans une classe :

                      <#@ template debug="false" hostspecific="false" language="C#" #>
    <#@ output extension=".cs" #>
    <# var properties = new string [] {"P1", "P2", "P3"}; #>
    class MyGeneratedClass {
    <# 
      foreach (string propertyName in properties)
      { #>
      private int <#= propertyName #> = 0;
    <# } #>
    }
    
    <#@ template debug="false" hostspecific="false" language="VB" #>
    <#@ output extension=".cs" #>
    <# Dim properties = {"P1", "P2", "P3"} #>
    class MyGeneratedClass {
    <# 
       For Each propertyName As String In properties
    #>
      private int <#= propertyName #> = 0;
    <#
       Next
    #>
    }
    
  3. Enregistrez le fichier et inspectez le fichier généré, qui contient maintenant le code suivant :

    class MyGeneratedClass {
      private int P1 = 0; 
      private int P2 = 0;
      private int P3 = 0;
    }
    

Génération de code et de texte généré

Lorsque vous générez le code de programme, il est très important de ne pas confondre le code de génération qui s'exécute dans votre modèle et le code généré résultant qui est intégré à votre solution. Les deux langages ne doivent pas nécessairement être les mêmes.

L'exemple précédent a deux versions. Dans une version, le code de génération est en C#. Dans l'autre version, le code de génération est en Visual Basic. Toutefois, le texte généré par les deux versions est identique, et il s'agit d'une classe C#.

De la même façon, vous pouvez utiliser un modèle Visual C# pour générer du code en n'importe quel langage. Il n'est pas nécessaire que le texte généré provienne d'un langage particulier, ni qu'il corresponde à du code de programme.

Structuration de modèles de texte

Nous avons tendance à séparer le code du modèle en deux parties, comme cela est conseillé :

  • Une partie configuration, ou collecte de données, qui définit des valeurs dans les variables, mais ne contient pas de blocs de texte. Dans l'exemple précédent, cette partie est l'initialisation de properties.

    Elle porte parfois le nom de section « modèle », car elle construit un modèle stocké et lit généralement un fichier modèle.

  • La partie génération de texte (dans l'exemple, foreach(...){...}), qui utilise les valeurs des variables.

Il ne s'agit pas d'une séparation nécessaire, mais ce style facilite la lecture du modèle en réduisant la complexité de la partie qui inclut le texte.

Lecture de fichiers ou d'autres sources

Pour accéder à un fichier de modèle (model) ou une base de données model, votre code de modèle (template) peut utiliser des assemblys tels que System.XML. Pour accéder à ces assemblys, vous devez insérer des directives telles que celles-ci :

<#@ assembly name="System.Xml.dll" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.IO" #>

La directive assembly met l'assembly spécifié à la disposition de votre code de modèle, de la même manière que la section des références d'un projet Visual Studio. Vous n'avez pas besoin d'inclure une référence à System.dll, puisqu'il est référencé automatiquement. La directive import vous permet d'utiliser des types sans employer leur nom qualifié complet, de la même manière que la directive using dans un fichier programme ordinaire.

Par exemple, après avoir importé System.IO, vous pouvez écrire :

          <# var properties = File.ReadLines("C:\\propertyList.txt");#>
...
<# foreach (string propertyName in properties) { #>
...
<# For Each propertyName As String In 
             File.ReadLines("C:\\propertyList.txt")
#>

Ouverture d'un fichier avec un chemin d'accès relatif

Pour charger un fichier à partir d'un emplacement relatif au modèle de texte, vous pouvez utiliser this.Host.ResolvePath(). Pour utiliser this.Host, vous devez définir hostspecific="true" dans le template :

<#@ template debug="false" hostspecific="true" language="C#" #>

Ensuite, vous pouvez écrire par exemple :

<# string fileName = this.Host.ResolvePath("filename.txt");
  string [] properties = File.ReadLines(filename);
#>
...
<#  foreach (string propertyName in properties { #>
...
<# Dim fileName = Me.Host.ResolvePath("propertyList.txt")
   Dim properties = File.ReadLines(filename)
#>
...
<#   For Each propertyName As String In properties
...
#>

Vous pouvez également utiliser this.Host.TemplateFile, qui identifie le nom du fichier modèle actuel.

Le type de this.Host (en VB, Me.Host) est Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost.

Obtention de données de Visual Studio

Pour utiliser les services fournis dans Visual Studio, définissez l'attribut hostSpecific et chargez l'assembly EnvDTE. Par exemple :

<#@ template hostspecific="true" language="C#" #>
<#@ output extension=".txt" #>
<#@ assembly name="EnvDTE" #>
<#
  IServiceProvider serviceProvider = (IServiceProvider)this.Host;
  EnvDTE.DTE dte = (EnvDTE.DTE) serviceProvider.GetService(typeof(EnvDTE.DTE));
#>

Number of projects in this VS solution:  <#= dte.Solution.Projects.Count #>

Régénération automatique du code

En général, plusieurs fichiers d'une solution Visual Studio sont générés avec un même modèle (model) d'entrée. Chaque fichier est généré à partir de son propre modèle (template) ; en revanche, les modèles (templates) font tous référence au même modèle (model).

Si le modèle (model) source est modifié, vous devez réexécuter tous les modèles (templates) de la solution. Pour exécuter manuellement cette opération, cliquez sur Transformer tous les modèles dans la barre d'outils de l'Explorateur de solutions.

Si vous avez installé le kit de développement logiciel Visual Studio Visualization and Modeling SDK, vous pouvez faire en sorte que tous les modèles (templates) soient transformés automatiquement chaque fois que vous exécutez une génération. Pour ce faire, modifiez votre fichier projet (.csproj ou .vbproj) dans un éditeur de texte et ajoutez les lignes suivantes à la fin du fichier, après toutes les autres instructions <import> :

<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\TextTemplating\v10.0\Microsoft.TextTemplating.targets" />
<PropertyGroup>
   <TransformOnBuild>true</TransformOnBuild>
   <!-- Other properties can be inserted here -->
</PropertyGroup>

Pour plus d'informations, consultez Génération de code dans un processus de génération.

Signalement des erreurs

Pour placer des messages d'erreur et d'avertissement dans la fenêtre d'erreur Visual Studio, vous pouvez utiliser les méthodes suivantes :

Error("An error message");
Warning("A warning message");

Conversion d'un fichier existant en modèle

Une caractéristique utile des modèles réside dans le fait qu'ils sont très semblables aux fichiers qu'ils génèrent à mesure que le code de programme y est inséré. Elle suggère une méthode efficace pour la création des modèles. Commencez par créer un fichier ordinaire en tant que prototype, tel qu'un fichier Visual C#, puis introduisez progressivement le code de génération qui fait varier le fichier résultant.

Pour convertir un fichier texte existant en modèle au moment du design

  1. Dans votre projet Visual Studio, ajoutez un fichier du type que vous souhaitez générer, tel qu'un fichier .cs, .vb ou .resx.

  2. Testez le nouveau fichier afin de vous assurer qu'il fonctionne.

  3. Dans l'Explorateur de solutions, remplacez l'extension du nom du fichier par .tt.

  4. Vérifiez les propriétés suivantes du fichier .tt :

    Outil personnalisé =

    TextTemplatingFileGenerator

    Action de génération =

    Aucun

  5. Insérez les lignes suivantes au début du fichier :

    <#@ template debug="false" hostspecific="false" language="C#" #>
    <#@ output extension=".cs" #>
    

    Si vous voulez écrire le code de génération de votre modèle en Visual Basic, affectez à l'attribut language la valeur "VB" au lieu de "C#".

    Définissez l'attribut extension à l'extension de nom de fichier correspondant au type de fichier que vous voulez générer (par exemple, .cs, .resx ou .xml).

  6. Enregistrez le fichier.

    Un fichier subsidiaire est créé avec l'extension spécifiée. Ses propriétés sont adaptées au type de fichier. Par exemple, la propriété Action de génération d'un fichier .cs sera Compiler.

    Vérifiez que le fichier généré comporte le même contenu que le fichier d'origine.

  7. Identifiez une partie du fichier que vous voulez faire varier. Par exemple, une partie qui apparaît uniquement dans certaines conditions, ou bien une partie qui se répète ou dont les valeurs spécifiques varient. Insérez le code de génération. Enregistrez le fichier et vérifiez que le fichier subsidiaire est correctement généré. Répétez cette étape.

Instructions relatives à la génération de code

Consultez Instructions relatives à l'écriture de modèles de texte T4.

Étapes suivantes

Étape suivante

Rubrique

Écriture et débogage d'un modèle de texte plus avancé avec du code utilisant des fonctions auxiliaires, des fichiers inclus et des données persistantes.

Écriture d'un modèle de texte T4

Génération de documents à partir de modèles au moment de l'exécution.

Génération de texte durant l'exécution à l'aide de modèles de texte T4 prétraités

Exécution de la génération de texte en dehors de Visual Studio.

Génération de fichiers avec l'utilitaire TextTransform

Transformation de vos données sous la forme d'un langage spécifique à un domaine.

Génération de code à partir d'un langage spécifique à un domaine

Écriture de processeurs de directive pour la transformation de vos propres sources de données.

Personnalisation d'une transformation de texte T4

Voir aussi

Autres ressources

Instructions relatives à l'écriture de modèles de texte T4

Historique des modifications

Date

Historique

Motif

Octobre 2010

Exemples VB ajoutés.

Instructions déplacées vers une rubrique séparée.

Améliorations apportées aux informations.