Écriture d'un modèle de texte T4
Un modèle de texte contient le texte qu'il permettra de générer. Par exemple, un modèle qui crée une page Web contiendra « <html>… » et toutes les autres parties standard d'une page HTML. Des blocs de contrôle, qui sont des fragments de code de programme, sont insérés dans le modèle. Les blocs de contrôle fournissent des valeurs variables et autorisent les parties de texte conditionnelles et répétées.
Cette structure facilite le développement d'un modèle car vous pouvez commencer avec un prototype du fichier généré et insérer de façon incrémentielle des blocs de contrôle qui font varier le résultat.
Les modèles de texte sont composés des parties suivantes :
Directives : éléments qui contrôlent la façon dont le modèle est traité.
Blocs de texte : contenu copié directement dans la sortie.
Blocs de contrôle : code de programme qui insère des valeurs variables dans le texte et contrôle les parties conditionnelles ou répétées de ce dernier.
Pour tester les exemples de cette rubrique, copiez-les dans un fichier modèle comme décrit dans Génération de code durant la conception à l'aide de modèles de texte T4. Après avoir modifié le fichier modèle, enregistrez-le, puis inspectez le fichier .txt de sortie.
Directives
Les directives de modèle de texte fournissent des instructions générales au moteur de création de modèles de texte concernant la façon dont le code de transformation et le fichier de sortie doivent être générés.
Par exemple, la directive suivante spécifie que le fichier de sortie doit comporter une extension .txt :
<#@ output extension=".txt" #>
Pour plus d'informations sur les directives, consultez Directives de modèles de texte T4.
Blocs de texte
Un bloc de texte insère du texte directement dans le fichier de sortie. Il n'existe aucune mise en forme spéciale pour les blocs de texte. Par exemple, le modèle de texte suivant produira un fichier texte qui contient le mot « Hello » :
<#@ output extension=".txt" #>
Hello
Blocs de contrôle
Les blocs de contrôle sont des sections du code de programme qui sont utilisées pour transformer les modèles. Le langage par défaut est C#, mais pour utiliser Visual Basic, vous pouvez écrire la directive suivante au début du fichier :
<#@ template language="VB" #>
Le langage dans lequel vous écrivez le code dans les blocs de contrôle n'est pas lié au langage du texte qui est généré.
Blocs de contrôle standard
Un bloc de contrôle standard est une section du code de programme qui génère une partie du fichier de sortie.
Vous pouvez combiner un nombre quelconque de blocs de texte et de blocs de contrôle standard dans un fichier modèle. Toutefois, vous ne pouvez pas placer un bloc de contrôle à l'intérieur d'un autre. Chaque bloc de contrôle standard est délimité par les symboles <# ... #>.
Par exemple, si vous utilisez les blocs de contrôle et de texte suivants, le fichier de sortie contiendra la ligne « 0, 1, 2, 3, 4 Hello! » :
<#
for(int i = 0; i < 4; i++)
{
Write(i + ", ");
}
Write("4");
#> Hello!
Au lieu d'utiliser des instructions Write() explicites, vous pouvez entrelacer du texte et du code. L'exemple suivant imprime « Hello! » quatre fois :
<#
for(int i = 0; i < 4; i++)
{
#>
Hello!
<#
}
#>
Vous pouvez insérer un bloc de texte partout où une instruction Write(); est autorisée dans le code.
Notes
Lorsque vous incorporez un bloc de texte dans une instruction composée telle qu'une boucle ou une instruction conditionnelle, placez toujours le bloc de texte entre accolades {...}
Blocs de contrôle d'expression
Un bloc de contrôle d'expression évalue une expression et la convertit en chaîne. Celle-ci est insérée dans le fichier de sortie.
Les blocs de contrôle d'expression sont délimités par les symboles <#= ... #>
Par exemple, si vous utilisez le bloc de contrôle suivant, le fichier de sortie contient « 5 » :
<#= 2 + 3 #>
Notez que le symbole ouvrant comporte trois caractères « <#= ».
L'expression peut inclure toute variable se trouvant dans la portée. Par exemple, le bloc suivant imprime des lignes avec des numéros :
<#@ output extension=".txt" #>
<#
for(int i = 0; i < 4; i++)
{
#>
This is hello number <#= i+1 #>: Hello!
<#
}
#>
Blocs de contrôle de fonctionnalité de classe
Un bloc de contrôle de fonctionnalité de classe définit des propriétés, des méthodes ou tout autre code qui ne doit pas être inclus dans la transformation principale. Les blocs de fonctionnalité de classe sont fréquemment utilisés pour les fonctions d'assistance. En général, ils sont placés dans des fichiers séparés afin de pouvoir être inclus dans plusieurs modèles de texte.
Les blocs de contrôle de fonctionnalité de classe sont délimités par les symboles <#+ ... #>
Par exemple, le fichier modèle suivant déclare et utilise une méthode :
<#@ 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;
}
#>
Les fonctionnalités de classe doivent être placées à la fin du fichier dans lequel elles sont écrites. Toutefois, vous pouvez inclure (<#@include#>) un fichier contenant une fonctionnalité de classe, même si la directive include est suivie de texte et de blocs standard.
Pour plus d'informations sur les blocs de contrôle, consultez Blocs de contrôle des modèles de texte T4.
Possibilité d'inclure des blocs de texte dans les blocs de fonctionnalité de classe
Vous pouvez écrire une méthode qui génère du texte. Par exemple :
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 #>.
<#
}
#>
Il est particulièrement utile de placer une méthode qui génère du texte dans un fichier séparé pouvant être inclus dans plusieurs modèles.
Utilisation de définitions externes
Assemblys
Les blocs de code de votre modèle peuvent utiliser des types qui sont définis dans les assemblys .NET les plus fréquemment employés, tels que System.dll. En outre, vous avez la possibilité de référencer d'autres assemblys .NET ou vos propres assemblys. Vous pouvez fournir un nom de chemin ou le nom fort d'un assembly :
<#@ assembly name="System.Xml" #>
Vous devez utiliser des noms de chemins d'accès absolus ou des noms de macros standard dans le nom de chemin d'accès. Par exemple :
<#@ assembly name="$(SolutionDir)library\MyAssembly.dll" #>
Pour obtenir la liste des macros, consultez Macros pour les propriétés et les commandes de génération.
La directive assembly n'a aucun effet dans un modèle de texte prétraité.
Pour plus d'informations, consultez Directive d'assembly T4.
Espaces de noms
La directive import est identique à la clause using en C# ou à la clause imports en Visual Basic. Elle vous permet de faire référence aux types présents dans votre code sans utiliser de nom qualifié complet :
<#@ import namespace="System.Xml" #>
Vous pouvez utiliser autant de directives assembly et import que vous le voulez. Vous devez les placer avant les blocs de texte et de contrôle.
Pour plus d'informations, consultez Directive d'importation T4.
Inclusion de code et de texte
La directive include insère du texte d'un autre fichier modèle. Par exemple, la directive suivante insère le contenu de test.txt.
<#@ include file="c:\test.txt" #>
Le contenu inclus est traité presque comme s'il faisait partie du modèle de texte d'inclusion. Toutefois, vous pouvez inclure un fichier qui contient un bloc de fonctionnalité de classe <#+...#> même si la directive include est suivie de texte ordinaire et de blocs de contrôle standard.
Pour plus d'informations, consultez Directive d'inclusion T4.
Méthodes utilitaires
Plusieurs méthodes telles que Write() sont toujours disponibles dans un bloc de contrôle. Il s'agit notamment de méthodes vous permettant de mettre en retrait la sortie et de signaler des erreurs.
Vous pouvez également écrire votre propre ensemble de méthodes utilitaires.
Pour plus d'informations, consultez Méthodes utilitaires de modèle de texte T4.
Transformation de données et de modèles
L'application la plus utile d'un modèle (template) de texte est la génération de données en fonction du contenu d'une source telle qu'un modèle (model), une base de données ou un fichier de données. Votre modèle extrait et remet en forme les données. Une collection de modèles peut transformer une telle source en plusieurs fichiers.
Plusieurs approches permettent de lire le fichier source.
Lecture d'un fichier dans le modèle de texte. Il s'agit de la méthode la plus simple pour intégrer des données dans le modèle :
<#@ import namespace="System.IO" #>
<# string fileContent = File.ReadAllText(@"C:\myData.txt"); ...
Chargement d'un fichier en tant que modèle navigable. Une méthode plus performante consiste à lire les données en tant que modèle, dans lequel votre code de modèle de texte peut naviguer. Par exemple, vous pouvez charger un fichier XML et naviguer dans ce dernier avec des expressions XPath. Vous avez également la possibilité d'utiliser xsd.exe pour créer un ensemble de classes vous permettant de lire les données XML.
Modification du fichier modèle dans un diagramme ou un formulaire. Les Outils de langage spécifique à un domaine vous permettent de modifier un modèle comme un diagramme ou un Windows Form. Vous pouvez ainsi discuter plus facilement du modèle avec les utilisateurs de l'application générée. Les Outils de langage spécifique à un domaine créent également un ensemble de classes fortement typées qui reflètent la structure du modèle. Pour plus d'informations, consultez Génération de code à partir d'un langage spécifique à un domaine.
Utilisation d'un modèle UML. Vous pouvez générer du code à partir d'un modèle UML. L'avantage de cette méthode réside dans le fait que le modèle peut être modifié comme un diagramme dans une notation familière. En outre, vous n'avez pas besoin de concevoir le diagramme. Pour plus d'informations, consultez Comment : générer des fichiers à partir d'un modèle UML.
Chemins d'accès de fichier relatifs
Si vous souhaitez référencer un fichier dans un emplacement par rapport au modèle de texte, utilisez this.Host.ResolvePath(). Vous devez également définir hostspecific="true" dans la directive 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 #>
Vous pouvez également obtenir d'autres services fournis par l'hôte. Pour plus d'informations, consultez Accès à Visual Studio ou d'autres hôtes à partir d'un modèle de texte T4.
Les modèles de texte s'exécutent dans un AppDomain séparé.
Vous devez savoir qu'un modèle de texte s'exécute dans un AppDomain qui est distinct de l'application principale. Dans la plupart des cas, ce n'est pas important, mais vous pouvez être confronté à des restrictions dans certaines situations complexes. Par exemple, si vous souhaitez que des données passent ou non par le modèle à partir d'un service séparé, le service doit fournir une API sérialisable.
Modification de modèles
Des éditeurs de modèles de texte spécialisés peuvent être téléchargés à partir de la Galerie en ligne du Gestionnaire d'extensions. Dans le menu Outils, cliquez sur Gestionnaire d'extensions. Cliquez sur Galerie en ligne, puis utilisez l'outil de recherche.
Rubriques connexes
Tâche |
Rubrique |
---|---|
Écriture d'un modèle. |
|
Génération de texte à l'aide du code de programme. |
|
Génération de fichiers dans une solution Visual Studio. |
Génération de code durant la conception à l'aide de modèles de texte T4 |
Exécution de la génération de texte en dehors de Visual Studio. |
|
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. |
Historique des modifications
Date |
Historique |
Motif |
---|---|---|
Mars 2011 |
Utilisez des macros dans la directive Assembly. |
Commentaires client. |