Introduction au template T4

16 janvier 2013

C#, Non classé

 

Introduction

Le template T4 est apparu pour la première fois dans Visual Studio 2005.  Il s’agit d’un outil pour générer automatiquement et dynamiquement du code au sein de projets.

Les applications à ce genre d’utilitaire sont nombreuses et pour une première approche, nous resterons sur un cas simple : la génération automatique de classes C#.

 

Pour ce suivre ce tutoriel, vous avez besoin de Visual Studio 2008 ou 2010 (je me base sur celui-ci, il sera donc plus facile de me suivre) La version 2012 est relativement différente puisqu’elle gère elle-même le template T4. J’aborderai ce point dans un autre article.

NB : Vous verrez sur les captures d’écran que mon Visual Studio est en anglais, mais je pense que cela ne posera pas de problème pour suivre l’exercice. De plus, je vous recommande vivement d’utiliser la version anglophone. D’abord parce que les traductions ce n’est pas trop ça. Ensuite, parce que le MSDN est en majorité en anglais et c’est bien plus facile pour s’en sortir. Enfin, parce que j’ai déjà eu des soucis avec des addons, tools, et autres qui ne fonctionnaient pas pcq que mon Visual studio était en Français (et non en anglais).

Présentation

T4 peut-être utilisé avec ADO.NET, ASP.NET, WPF, etc. Il se sert d’une syntaxe qui lui est propre avec quatre types de balises :

Les directives

Ce sont des informations sur notre template T4 qui permettent de définir sont comportement. Elles se présentent sous la forme suivantes :

1
<#@ DirectiveName [Attribute = "Value"] #>

On retrouve cinq sous types :

Les directives d’Output :

Comme mentionné plus haut dans cet article, le template T4 est en quelque sorte un canevas pour générer du code. Celui-ci devra donc bien être « écrit » quelque part sinon il ne sera d’aucune utilité.

On va donc l’écrire dans un fichier. Les directives d’Output permettent de définir l’extension du fichier de sortie.

1
<#output extension=".cs"#>

D’autres attributs peuvent être utilisé comme par exemple le type d’encodage du fichier :

1
<#@output extension=".cs" encoding="UTF8"#>

Les directives de Template :

Grâce à ces directives, on va pouvoir définir les caractéristiques globales du template :

  • Language : spécifie le langage du Template T4 : soit VB, soit C#;
  • Debug : active ou désactive le débogage;
  • HostSpecific : permet d’autoriser ou de refuser l’accès à l’objet host;
  • Inherits : spécifie la classe de génération dont le template hérite (facultatif).
1
<#@ template debug="false" HostSpecific="true"  language="C#" #>

Les directives d’Assembly :

Ces directives permettent d’ajouter des références au template.

1
<#@ assembly name="System.Collection" #>

Certaines assemblies sont déjà importées par défaut dans le template, il n’est donc pas nécessaire de les importer :

  • System ;
  • Microsoft.VisualStudio.TextTemplating.VSHost ;
  • Microsoft.VisualStudio.TextTemplating.dll ;
  • mscorlib.

Les directives d’Import :

Elles remplacent les using que l’on utilise traditionnellement dans les classes en C#.

1
<#@ import namespace="System.Collections.Generic #>

Les directives d’Include :

Ce type de directives permet d’inclure des autres templates T4 directement dans notre template.

1
<#@ include file="D:\template\temp1.tt" #>

Les blocs de codes

Ils sont représentés entre les balises <#>

L’affichage du texte depuis du code

Pour afficher du texte, rien de plus simple, il suffit de le placer entre les balises <#=>

1
<#= VotreTexte #>

Les class feature blocks

Ces blocs sont particulièrement utiles car ils permettent la création de méthodes et de classes dans votre template. Voici un exemple :

1
<#@= SayHelloToUser("Benoît") #>
2
3
<#+
4
public String SayHelloToUser(String userName)
5
{
6
       return "Hello "+userName;
7
}
8
#>

Un cas pratique (simple)

Étant donné qu’il ne s’agit que d’une introduction au template T4, j’ai pris un cas pratique extrêmement simple, et on peut le dire, un peu ridicule, mais au moins il sera facile à comprendre pour chacun.

Tout d’abord ouvrez, Visual Studio 2010 et créez un nouveau projet de « Bibliothèques de classes ».

Création du projetCréation du projet

Supprimez la classe Class1.cs, créez un nouveau dossier « Classes » et ajoutez-y quatre classes : Campus, Course, Room et Teacher :

Création des classesCréation des classes

Ensuite, faites un clic droit sur votre projet et ajoutez un nouvel élément de type Code File (fichier source). Nommez ce nouvel élément MyTemplate.tt (attention à bien spécifier l’extension .tt).

Création du fichier de templateCréation du fichier de template

Double-cliquez sur le fichier MyTemplate.tt pour l’ouvrir dans l’éditeur. Nous allons enfin pouvoir commencer à compléter notre template.

Tout d’abord, écrivons le header du fichier template :

 C# |  copy code | ?
1
<#@ template debug="false" hostspecific="true" language="C#" #>
2
<#@ output extension=".cs" #>
3
<#@ import nameSpace="System.IO" #>

Dans le header, on désactive le débogage, on spécifie que le langage utilisé sera le C# et que le fichier de sortie sera un .cs (donc une classe C#). On importe également le namespace « System.IO » qui nous permettra de générer le fichier de sortie.

On déclare les variables en les initialisant.

La génération de notre fichier de sortie va se faire en plusieurs temps :

D’abord on va écrire les usings nécessaires et déclarer le namespace,  la classe, etc. au début du fichier.

Ensuite, on va lire les noms des classes présentes dans le dossier « Classes » et écrire une propriété de la forme « public Type type {get; set ;} » dans la classe générée.

Enfin, on ajoute une méthode ToString() et on ferme la déclaration de la classe et du namespace.

 C# |  copy code | ?
01
<#
02
string generatedClassName = "Session";
03
string nameSpace = "T4example";
04
string folderName = "Classes";
05
DirectoryInfo templateDir = new FileInfo(Host.TemplateFile).Directory;
06
07
WriteUsings(nameSpace, folderName);
08
WriteBeginOfFile(nameSpace, generatedClassName);
09
10
foreach(FileInfo file in new DirectoryInfo(templateDir.FullName + @"\" + folderName).GetFiles())
11
{
12
    WriteProperty(file.Name.Split('.').GetValue(0).ToString());
13
}
14
15
WriteToString();
16
WriteEndOfFile();
17
#>

Déclarons maintenant, les différentes fonctions utilisées dans le template.Tout le code déclaré en dehors des crochets (« <#> ») est automatiquement recopié dans le fichier de sortie. Faites donc attention où vous placez vos accolades ouvrantes et fermantes (les espaces et tabulations sont également pris en compte).

 C# |  copy code | ?
01
<#+
02
private void WriteUsings(string space, string folderName)
03
{
04
#>
05
using System;
06
using <#= space + "." + folderName #>;
07
08
<#+
09
}
10
11
private void WriteBeginOfFile(string space, string generatedClassName)
12
{
13
14
#>
15
namespace <#=  space #>
16
{
17
     // Auto Generated class by Template T4
18
     public class <#=  generatedClassName #>
19
     {
20
<#+
21
}
22
23
private void WriteEndOfFile()
24
{
25
#>
26
    }
27
}
28
<#+
29
}
30
31
private void WriteProperty(string name)
32
{
33
#>
34
     public <#= String.Format("{0} {1}",name, name.ToLower()) #>  {get; set; } //Auto Property
35
36
<#+
37
}
38
39
private void WriteToString()
40
{
41
#>
42
     public String ToString() //Auto ToString() Method
43
     {
44
         return String.Format("The session of {0} teach by {1} will take place at campus {2} in the room {3}",room,teacher,campus,room);
45
     }
46
<#+
47
}
48
49
#>

Voici le résultat final :

 C# |  copy code | ?
01
using System;
02
using T4example.Classes;
03
04
namespace T4example
05
{
06
    // Auto Generated class by Template T4
07
    public class Session
08
    {
09
        public Campus campus  {get; set; } //Auto Property
10
11
        public Course course  {get; set; } //Auto Property
12
13
        public Room room  {get; set; } //Auto Property
14
15
        public Teacher teacher  {get; set; } //Auto Property
16
17
        public String ToString() //Auto ToString() Method
18
        {
19
            return String.Format("The session of {0} teach by {1} will take place at campus {2} in the room {3}",room,teacher,campus,room);
20
        }
21
    }
22
}

Et voilà ce tutoriel est terminé. Les sources sont disponibles ici :

sciencejp |
SOS planète |
Mathématiques en Terminale S |
Unblog.fr | Créer un blog | Annuaire | Signaler un abus | La récupération est-elle la...
| ana112big
| Archéoslogos