Partager via


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

Ces instructions générales peuvent être utiles si vous générez du code de programme ou d'autres ressources d'application dans Visual Studio. Il ne s'agit pas de règles figées.

Instructions pour les modèles T4 au moment du design

Les modèles T4 au moment du design sont des modèles qui génèrent du code dans votre projet Visual Studio au moment du design. Pour plus d'informations, consultez Génération de code durant la conception à l'aide de modèles de texte T4.

  • Générez des aspects variables de l'application.
    La génération de code est très utile pour les aspects de l'application qui peuvent changer au cours du projet ou changeront entre différentes versions de l'application. Séparez ces aspects variables des aspects plus constants de façon à pouvoir déterminer plus facilement ce qui doit être généré. Par exemple, si votre application fournit un site Web, séparez les fonctions de serveur de pages standard de la logique qui définit les chemins de navigation entre les pages.

  • Encodez les aspects variables dans un ou plusieurs modèles (models) sources.
    Un modèle (model) est un fichier ou une base de données que chaque modèle (template) lit de façon à obtenir des valeurs spécifiques pour les parties variables du code à générer. Les modèles (models) peuvent correspondre à des bases de données, des fichiers XML de votre propre conception, des diagrammes ou des langages spécifiques à un domaine. En général, un modèle est utilisé pour générer de nombreux fichiers dans un projet Visual Studio. Chaque fichier est généré à partir d'un modèle séparé.

    Vous pouvez utiliser plusieurs modèles (models) dans un projet. Par exemple, vous pouvez définir un modèle pour la navigation entre les pages Web et un modèle séparé pour la disposition des pages.

  • Concernant le modèle, mettez l'accent sur les besoins et le vocabulaire des utilisateurs, pas sur votre implémentation.
    Par exemple, dans une application de site Web, vous vous attendez à ce que le modèle fasse référence à des pages Web et des liens hypertexte.

    Idéalement, choisissez une forme de présentation adaptée au genre d'informations que le modèle représente. Par exemple, un modèle de chemins de navigation via un site Web peut correspondre à un diagramme constitué de cases et de flèches.

  • Testez le code généré.
    Utilisez les tests manuels ou automatisés pour vérifier que le code résultant répond aux besoins des utilisateurs. Évitez de générer des tests à partir du modèle utilisé pour générer le code.

    Dans certains cas, des tests généraux peuvent être exécutés directement sur le modèle. Par exemple, vous pouvez écrire un test permettant de vérifier que chaque page du site Web est accessible par le biais de la navigation à partir de n'importe quelle autre page.

  • Tenir compte du code personnalisé : générer des classes partielles
    Tenez compte du code que vous écrivez manuellement en plus du code généré. Il est rare qu'un schéma de génération de code puisse représenter toutes les variantes possibles. Par conséquent, vous devrez probablement compléter ou remplacer une partie du code généré. Lorsque les données générées sont écrites dans un langage .NET tel que Visual C# ou Visual Basic, deux stratégies sont particulièrement utiles :

    • Les classes générées doivent être partielles. Vous pouvez ainsi ajouter du contenu au code généré.

    • Les classes doivent être générées par paires, l'une héritant de l'autre. La classe de base doit contenir toutes les propriétés et méthodes générées, tandis que la classe dérivée doit contenir uniquement les constructeurs. Le code que vous écrivez manuellement peut de cette façon remplacer l'une des méthodes générées.

    Dans d'autres langages générés tels que XML, utilisez la directive <#@include#> pour créer des combinaisons simples de contenus généré et écrit manuellement. Dans des cas plus complexes, vous devrez peut-être écrire une étape de post-traitement qui combine le fichier généré avec les fichiers écrits manuellement.

  • Déplacer le matériel commun vers les fichiers Include ou les modèles au moment de l'exécution
    Pour éviter de répéter du code et des blocs de texte similaires dans plusieurs modèles, utilisez la directive <#@ include #>. Pour plus d'informations, consultez Directive d'inclusion T4.

    Vous pouvez également générer des modèles de texte au moment de l'exécution dans un projet séparé, puis les appeler à partir du modèle au moment du design. Pour ce faire, utilisez la directive <#@ assembly #> afin d'accéder au projet séparé. Pour obtenir des exemples, consultez "Inheritance in Text Templates" sur le blog de Gareth Jones.

  • Envisager de déplacer des grands blocs de code dans un assembly séparé
    Si vous possédez de grands blocs de code et des blocs de fonctionnalité de classe, il peut être utile de déplacer une partie de ce code vers les méthodes que vous compilez dans un projet séparé. Vous pouvez utiliser la directive <#@ assembly #> pour accéder au code dans le modèle. Pour plus d'informations, consultez Directive d'assembly T4.

    Vous pouvez placer les méthodes dans une classe abstraite dont le modèle peut hériter. La classe abstraite doit hériter de TextTransformation. Pour plus d'informations, consultez Directive du modèle T4.

  • Générer du code, pas des fichiers de configuration
    Une méthode d'écriture d'une application variable consiste à écrire du code de programme générique qui accepte un fichier de configuration. Une application écrite de cette façon est très flexible et peut être reconfigurée en fonction de l'évolution des besoins de l'entreprise, sans qu'il soit nécessaire de la reconstruire. Toutefois, un inconvénient de cette approche réside dans le fait que l'application sera moins performante qu'une autre plus spécifique. En outre, son code de programme sera plus difficile à lire et à mettre à jour, en partie parce qu'il doit toujours gérer les types les plus génériques.

    En revanche, une application dont les parties variables sont générées avant la compilation peut être fortement typée. Il est par conséquent beaucoup plus facile et plus fiable d'écrire du code manuellement et de l'intégrer aux parties générées du logiciel.

    Pour tirer pleinement partie de la génération de code, essayez de générer du code de programme au lieu des fichiers de configuration.

  • Utiliser un dossier Code généré
    Placez les modèles et les fichiers générés dans un dossier de projet nommé Generated Code pour indiquer clairement qu'il ne s'agit pas de fichiers devant être modifiés directement. Si vous créez du code personnalisé pour remplacer ou compléter les classes générées, placez ces classes dans un dossier nommé Custom Code. La structure d'un projet type se présente comme suit :

    MyProject
       Custom Code
          Class1.cs
          Class2.cs
       Generated Code
          Class1.tt
              Class1.cs
          Class2.tt
              Class2.cs
       AnotherClass.cs
    
    

Instructions pour les modèles T4 au moment de l'exécution (prétraités)

  • Déplacer le matériel commun vers des modèles hérités
    Vous pouvez utiliser l'héritage pour partager des méthodes et des blocs de texte entre des modèles de texte T4. Pour plus d'informations, consultez Directive du modèle T4.

    Vous pouvez également utiliser des fichiers Include qui ont des modèles au moment de l'exécution.

  • Déplacer des corps de code volumineux vers une classe partielle
    Chaque modèle au moment de l'exécution génère une définition de classe partielle qui a le même nom que le modèle. Vous pouvez écrire un fichier de code qui contient une autre définition partielle de la même classe. Vous pouvez ajouter des méthodes, des champs et des constructeurs à la classe de cette manière. Ces membres peuvent être appelés à partir des blocs de code dans le modèle.

    L'avantage est que le code est plus facile à écrire, car IntelliSense est disponible. De plus, vous pouvez obtenir une meilleure séparation entre la présentation et la logique sous-jacente.

    Par exemple, dans MyReportText.tt :

    The total is: <#= ComputeTotal() #>

    Dans MyReportText-Methods.cs :

    private string ComputeTotal() { ... }

  • Tenir compte du code personnalisé : fournir des points d'extension
    Envisagez de générer des méthodes virtuelles dans <#+ blocs de fonctionnalité de classe #>. Cela permet l'utilisation d'un modèle unique dans de nombreux contextes sans changement. Au lieu de modifier le modèle, vous pouvez générer une classe dérivée qui fournit la logique supplémentaire minimum. La classe dérivée peut être du code normal ou un modèle au moment de l'exécution.

    Par exemple, dans MyStandardRunTimeTemplate.tt :

    This page is copyright <#= CompanyName() #>.
    <#+ protected virtual string CompanyName() { return ""; } #>
    

    Dans le code d'une application :

    class FabrikamTemplate : MyStandardRunTimeTemplate
    {
      protected override string CompanyName() { return "Fabrikam"; }
    }
    ...
      string PageToDisplay = new FabrikamTemplate().TextTransform();
    

Instructions pour tous les modèles T4

  • Collecte de données séparée à partir de la génération de texte
    Dans la mesure du possible, évitez de mélanger les calculs et les blocs de texte. Dans chaque modèle de texte, utilisez le premier <# bloc de code #> pour définir des variables et exécuter des calculs complexes. Du premier bloc de texte jusqu'à la fin du modèle ou jusqu'au premier <#+ bloc de fonctionnalité de classe #>, évitez les expressions longues, les boucles et les conditions, à moins qu'elles contiennent des blocs de texte. Cette pratique simplifie la lecture et la gestion du modèle.

  • Ne pas utiliser .tt pour les fichiers Include
    Utilisez une extension de nom de fichier différente telle que .ttinclude pour les fichiers Include. Utilisez .tt uniquement pour les fichiers que vous souhaitez traiter comme des modèles de texte au moment de l'exécution ou du design. Dans certains cas, Visual Studio reconnaît les fichiers .tt et définit automatiquement leurs propriétés pour le traitement.

  • Commencez chaque modèle comme un prototype fixe.
    Écrivez un exemple du code ou du texte que vous voulez générer et assurez-vous qu'il est correct. Affectez-lui ensuite l'extension .tt et insérez de façon incrémentielle du code qui modifie le contenu en lisant le modèle.

  • Envisagez d'utiliser des modèles typés.
    Bien que vous puissiez créer un schéma XML ou de base de données pour vos modèles, il peut être utile de créer un langage spécifique à un domaine (DSL). L'avantage d'un DSL est qu'il génère une classe pour représenter chaque nœud dans le schéma et des propriétés pour représenter les attributs. Cela signifie que vous pouvez programmer le modèle d'entreprise. Par exemple :

    Team Members:
    <# foreach (Person p in team.Members) 
     { #> 
        <#= p.Name #> 
    <# } #>
    
  • Envisager d'utiliser des diagrammes pour vos modèles
    De nombreux modèles sont présentés et gérés le plus efficacement comme des tables de texte, surtout s'ils sont très volumineux.

    Toutefois, pour les besoins de l'entreprise, il est important de clarifier les jeux complexes de relations et de flux de travail ; les diagrammes sont le média le plus approprié. L'un des avantages d'un diagramme est qu'il est facile de discuter avec les utilisateurs et les autres parties prenantes. En générant du code à partir d'un modèle au niveau des besoins de l'entreprise, vous rendez votre code plus flexible lorsque les spécifications changent.

    Les diagrammes d'activités et de classes UML peuvent souvent être adaptés à ces fins. Vous pouvez également concevoir votre propre type de diagramme comme un langage spécifique au domaine (DSL). Le code peut être généré à partir d'UML et de langages spécifiques à un domaine. Pour plus d'informations, consultez Modélisation de l'application et Modélisation de l'application.

Voir aussi

Concepts

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

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