Génération de code dans un processus de génération
Vous pouvez appeler la transformation de texte dans le cadre du processus de génération d'une solution Visual Studio. Il existe des tâches de génération qui sont spécialisées pour la transformation de texte. Les tâches de génération T4 exécutent les modèles de texte au moment du design. En outre, elles compilent les modèles de texte (prétraités) au moment de l'exécution.
Il existe quelques différences en matière de possibilités offertes par les tâches de génération, selon le moteur de génération que vous utilisez. Lorsque vous générez la solution dans Visual Studio, un modèle de texte peut accéder à l'API Visual Studio (EnvDTE) si l'attribut hostspecific="true" est défini. Mais cela n'est pas vrai lorsque vous générez la solution à partir de la ligne de commande ou lorsque vous démarrez une génération serveur via Visual Studio. Dans ces situations, la génération est exécutée par MSBuild et un autre hôte T4 est utilisé.
Cela signifie que vous ne pouvez pas accéder aux éléments tels que les noms de fichiers projet de la même manière lorsque vous générez un modèle de texte dans MSBuild. Toutefois, vous pouvez passer les informations d'environnement aux modèles de texte et aux processeurs de directive en utilisant les paramètres de build.
Configurer vos ordinateurs
Pour activer les tâches de génération sur votre ordinateur de développement, installez le Kit de développement logiciel (SDK) de modélisation pour Visual Studio.
Si votre serveur de builds s'exécute sur un ordinateur sur lequel Visual Studio n'est pas installé, copiez les fichiers suivants sur l'ordinateur de build à partir de votre ordinateur de développement. Remplacez ‘*’ par les numéros de version les plus récents.
$(ProgramFiles)\MSBuild\Microsoft\VisualStudio\v*.0\TextTemplating
Microsoft.VisualStudio.TextTemplating.Sdk.Host.*.0.dll
Microsoft.TextTemplating.Build.Tasks.dll
Microsoft.TextTemplating.targets
$(ProgramFiles)\Microsoft Visual Studio *.0\VSSDK\VisualStudioIntegration\Common\Assemblies\v4.0
Microsoft.VisualStudio.TextTemplating.*.0.dll
Microsoft.VisualStudio.TextTemplating.Interfaces.*.0.dll (plusieurs fichiers)
Microsoft.VisualStudio.TextTemplating.VSHost.*.0.dll
$(ProgramFiles)\Microsoft Visual Studio *.0\Common7\IDE\PublicAssemblies\
- Microsoft.VisualStudio.TextTemplating.Modeling.*.0.dll
Pour modifier le fichier projet
Vous devrez modifier votre fichier projet pour configurer certaines fonctionnalités dans MSBuild.
Dans l'Explorateur de solutions, choisissez Décharger dans le menu contextuel de votre projet. Cela vous permet de modifier le fichier .csproj ou .vbproj dans l'éditeur XML.
Lorsque vous avez terminé la modification, choisissez Recharger.
Importation des cibles de la transformation de texte
Dans le fichier .vbproj ou .csproj, recherchez une ligne telle que :
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
ou
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
Après cette ligne, insérez l'importation de modèles de texte :
<!-- Optionally make the import portable across VS versions -->
<PropertyGroup>
<!-- Get the Visual Studio version – defaults to 10: -->
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<!-- Keep the next element all on one line: -->
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<!-- This is the important line: -->
<Import Project="$(VSToolsPath)\TextTemplating\Microsoft.TextTemplating.targets" />
Transformation des modèles d'une build
Il existe des propriétés que vous pouvez insérer dans votre fichier projet afin de contrôler la tâche de transformation :
Exécutez la tâche de transformation au début de chaque génération :
<PropertyGroup> <TransformOnBuild>true</TransformOnBuild> </PropertyGroup>
Remplacez les fichiers en lecture seule, par exemple, car ils ne sont pas vérifiés :
<PropertyGroup> <OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles> </PropertyGroup>
Transformez chaque modèle à chaque fois :
<PropertyGroup> <TransformOutOfDateOnly>false</TransformOutOfDateOnly> </PropertyGroup>
Par défaut, la tâche T4 MSBuild régénère un fichier de sortie s'il est antérieur à son fichier modèle, aux fichiers inclus ou aux fichiers qui ont été précédemment lus par le modèle ou par un processeur de directive qu'il utilise. Notez qu'il s'agit d'un test de dépendance beaucoup plus puissant que celui de la commande Transformer tous les modèles dans Visual Studio. Ce dernier ne fait que comparer les dates du fichier modèle et du fichier de sortie.
Pour exécuter uniquement les transformations de texte dans votre projet, appelez la tâche TransformAll :
msbuild myProject.csproj /t:TransformAll
Pour transformer un modèle de texte spécifique :
msbuild myProject.csproj /t:Transform /p:TransformFile="Template1.tt"
Vous pouvez utiliser des caractères génériques dans TransformFile :
msbuild dsl.csproj /t:Transform /p:TransformFile="GeneratedCode\**\*.tt"
Contrôle de code source
Il n'existe aucune intégration prédéfinie spécifique avec un système de contrôle de code source. Toutefois, vous pouvez ajouter vos propres extensions, par exemple pour extraire et archiver un fichier généré. Par défaut, la tâche de transformation de texte évite de remplacer un fichier en lecture seule. Lorsqu'un tel fichier est trouvé, une erreur est journalisée dans la liste d'erreurs de Visual Studio, et la tâche échoue.
Pour spécifier que les fichiers en lecture seule doivent être remplacés, insérez la propriété suivante :
<OverwriteReadOnlyOuputFiles>true</OverwriteReadOnlyOuputFiles>
À moins que vous ne personnalisiez l'étape de post-traitement, un avertissement sera consigné dans la liste d'erreurs lorsqu'un fichier est remplacé.
Personnalisation du processus de génération
La transformation de texte se produit avant les autres tâches du processus de génération. Pour définir les tâches appelées avant et après la transformation, définissez les propriétés $(BeforeTransform) et $(AfterTransform) :
<PropertyGroup>
<BeforeTransform>CustomPreTransform</BeforeTransform>
<AfterTransform>CustomPostTransform</AfterTransform>
</PropertyGroup>
<Target Name="CustomPreTransform">
<Message Text="In CustomPreTransform..." Importance="High" />
</Target>
<Target Name="CustomPostTransform">
<Message Text="In CustomPostTransform..." Importance="High" />
</Target>
Dans AfterTransform, vous pouvez référencer des listes de fichiers :
GeneratedFiles : liste des fichiers écrits par le processus. Pour les fichiers qui ont remplacé des fichiers en lecture seule existants, %(GeneratedFiles.ReadOnlyFileOverwritten) a la valeur true. Ces fichiers peuvent être extraits du contrôle de code source.
NonGeneratedFiles : liste des fichiers en lecture seule qui n'ont pas été remplacés.
Par exemple, vous définissez une tâche afin d'extraire GeneratedFiles.
OutputFilePath et OutputFileName
Ces propriétés sont utilisées uniquement par MSBuild. Elles n'affectent pas la génération du code dans Visual Studio. Elles redirigent le fichier de sortie généré vers un autre dossier ou fichier. Le dossier cible doit déjà exister.
<ItemGroup>
<None Include="MyTemplate.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<OutputFilePath>MyFolder</OutputFilePath>
<LastGenOutput>MyTemplate.cs</LastGenOutput>
</None>
</ItemGroup>
$(IntermediateOutputPath). est un dossier utile pour la redirection
Si vous spécifiez un nom de fichier de sortie, il est prioritaire par rapport à l'extension spécifiée dans la directive de sortie des modèles.
<ItemGroup>
<None Include="MyTemplate.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<OutputFileName>MyOutputFileName.cs</OutputFileName>
<LastGenOutput>MyTemplate.cs</LastGenOutput>
</None>
</ItemGroup>
Il est déconseillé de spécifier OutputFileName ou OutputFilePath si vous transformez également des modèles dans Visual Studio via la commande Transformer tous les modèles, ou si vous exécutez le générateur de fichier unique. Vous obtiendrez des chemins d'accès de fichiers distincts selon la façon dont vous avez déclenché la transformation. Cela peut vraiment prêter à confusion.
Ajout de chemins d'accès des références et Include
L'hôte possède un ensemble de chemins d'accès par défaut dans lesquels il recherche les assemblys référencés dans les modèles. Pour effectuer un ajout à cet ensemble :
<ItemGroup>
<T4ReferencePath Include="$(VsIdePath)PublicAssemblies\" />
<!-- Add more T4ReferencePath items here -->
</ItemGroup>
Pour définir les dossiers où rechercher les fichiers Include, fournissez une liste d'éléments délimités par des points-virgules. Généralement, vous effectuez l'ajout à la liste des dossiers existants.
<PropertyGroup>
<IncludeFolders>
$(IncludeFolders);$(MSBuildProjectDirectory)\Include;AnotherFolder;And\Another</IncludeFolders>
</PropertyGroup>
Passer les données de contexte de build dans les modèles
Vous pouvez définir des valeurs de paramètre dans le fichier projet. Par exemple, vous pouvez passer des propriétés de build et des variables d'environnement :
<ItemGroup>
<T4ParameterValues Include="ProjectFolder">
<Value>$(ProjectDir)</Value>
<Visible>false</Visible>
</T4ParameterValues>
</ItemGroup>
Dans un modèle de texte, définissez hostspecific dans la directive de modèle. Utilisez la directive parameter pour obtenir des valeurs :
<#@template language="c#" hostspecific="true"#>
<#@ parameter type="System.String" name="ProjectFolder" #>
The project folder is: <#= ProjectFolder #>
Dans un processeur de directive, vous pouvez appeler ResolveParameterValue :
string value = Host.ResolveParameterValue("-", "-", "parameterName");
Dim value = Host.ResolveParameterValue("-", "-", "parameterName")
Notes
ResolveParameterValue obtient des données uniquement à partir de T4ParameterValues lorsque vous utilisez MSBuild.Lorsque vous transformez le modèle à l'aide de Visual Studio, les paramètres ont des valeurs par défaut.
Utilisation de propriétés de projet dans les directives d'assembly et Include
Les macros Visual Studio telles que $(SolutionDir) ne fonctionnent pas dans MSBuild. Vous pouvez utiliser des propriétés de projet à la place.
Modifiez votre fichier projet .csproj ou .vbproj pour définir une propriété de projet. Cet exemple définit une propriété nommée myLibFolder :
<!-- Define a project property, myLibFolder: -->
<PropertyGroup>
<myLibFolder>$(MSBuildProjectDirectory)\..\libs</myLibFolder>
</PropertyGroup>
<!-- Tell the MSBuild T4 task to make the property available: -->
<ItemGroup>
<T4ParameterValues Include="myLibFolder">
<Value>$(myLibFolder)</Value>
</T4ParameterValues>
</ItemGroup>
Désormais, vous pouvez utiliser votre propriété de projet dans les directives d'assembly et Include :
<#@ assembly name="$(myLibFolder)\MyLib.dll" #>
<#@ include file="$(myLibFolder)\MyIncludeFile.t4" #>
Ces directives obtiennent des valeurs à partir de T4parameterValues dans MSBuild et les hôtes Visual Studio.
Q et R
Pourquoi vouloir transformer des modèles sur le serveur de builds ? J'ai déjà transformé des modèles dans Visual Studio avant d'archiver mon code.
Si vous mettez à jour un fichier inclus ou tout autre fichier lu par le modèle, Visual Studio ne transforme pas le fichier automatiquement. La transformation des modèles dans le cadre de la build permet de s'assurer que tout est à jour.
Quelles sont les autres options en matière de transformation de modèles de texte ?
L'utilitaire TextTransform peut être utilisé dans les scripts de commandes. Dans la plupart des cas, il est plus facile d'utiliser MSBuild.
Les modèles de texte au moment du design sont transformés par Visual Studio.
Les modèles de texte au moment de l'exécution sont transformés au moment de l'exécution dans votre application.
En lire plus
Vous trouverez de bons conseils dans le modèle T4 MSbuild, $(VSToolsPath)\TextTemplating\Microsoft.TextTemplating.targets
Écriture d'un modèle de texte T4
Kit de développement logiciel (SDK) de visualisation et de modélisation de Visual Studio