T4-Include-Direktive
In einer Textvorlage in Visual Studio können Sie Text aus einer anderen Datei mit einer <#@include#>
-Anweisung einfügen. Sie können include
-Anweisungen an einer beliebigen Stelle in einer Textvorlage platzieren, und zwar vor dem ersten Klassenfunktionsblock <#+ ... #>
. Die eingeschlossenen Dateien können auch include
-Direktiven und andere Direktiven enthalten. Dadurch können Sie Vorlagencode und Text mit Codebausteinen zwischen Vorlagen freigeben.
Verwenden von Include-Anweisungen
<#@ include file="filePath" [once="true"] #>
filePath
kann absolut oder relativ zur aktuellen Vorlagendatei sein.Außerdem können bestimmte Visual Studio-Erweiterungen eigene Verzeichnisse angeben, in denen nach Includedateien gesucht werden soll. Wenn Sie z. B. das SDK für Visualisierung und Modellierung (DSL-Tools) installiert haben, wird der Includeliste der folgende Ordner hinzugefügt:
Program Files\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft\DSL SDK\DSL Designer\11.0\TextTemplates
.Diese zusätzlichen Includeordner können von der Dateierweiterung der einschließenden Datei abhängen. Zum Beispiel können nur einschließende Dateien mit der Dateierweiterung
.tt
auf den Includeordner der DSL-Tools zugreifen.filePath
kann durch "%" begrenzte Umgebungsvariablen einschließen. Beispiel:<#@ include file="%HOMEPATH%\MyIncludeFile.t4" #>
Für einen Namen einer eingeschlossenen Datei muss nicht die Erweiterung
".tt"
verwendet werden.Sie können für eingeschlossene Dateien ggf. eine andere Erweiterung verwenden, z. B.
".t4"
. Dies liegt daran, dass beim Hinzufügen einer.tt
-Datei zu einem Projekt Visual Studio die Eigenschaft Benutzerdefiniertes Tool automatisch aufTextTemplatingFileGenerator
festlegt. Normalerweise sollen eingeschlossene Dateien nicht einzeln transformiert werden.Andererseits sollten Sie beachten, dass die Dateierweiterung in einigen Fällen Einfluss darauf hat, welche zusätzlichen Ordner nach Includedateien durchsucht werden. Dies könnte wichtig sein, wenn eine eingeschlossene Datei andere Dateien enthält.
Der eingeschlossene Inhalt wird fast so verarbeitet, als wäre er Teil der jeweiligen Textvorlage. Sie können jedoch auch dann eine Datei einschließen, die einen Klassenfunktionsblock
<#+...#>
enthält, wenn nach derinclude
-Anweisung normale Text- und Standardkontrollblöcke eingefügt werden.Verwenden Sie
once="true"
, um sicherzustellen, dass eine Vorlage nur einmal eingeschlossen wird, auch wenn sie von mehr als einer Includedatei aufgerufen wird.Dieses Feature erleichtert das Erstellen einer Bibliothek wiederverwendbarer T4-Codeschnipsel, die Sie nach Belieben einschließen können, ohne sich Gedanken darüber zu machen, dass sie in einigen anderen Schnipseln bereits enthalten sind. Angenommen, Sie verfügen über eine Bibliothek mit sehr differenzierten Codeschnipseln, bei denen es um die Vorlagenverarbeitung und die C#-Generierung geht. Diese werden wiederum von einigen eher aufgabenspezifischen Hilfsprogrammen verwendet, z. B. von Aufgaben zum Generieren von Ausnahmen, die Sie über eine eher anwendungsspezifische Vorlage verwenden können. Wenn Sie das Abhängigkeitsdiagramm zeichnen, sehen Sie, dass einige Ausschnitte mehrmals eingeschlossen würden. Die Parameter
once
verhindert aber die darauffolgenden Einschlüsse.MyTextTemplate.tt:
<#@ output extension=".txt" #>
Output message 1 (from top template).
<#@ include file="TextFile1.t4"#>
Output message 5 (from top template).
<#
GenerateMessage(6); // defined in TextFile1.t4
AnotherGenerateMessage(7); // defined in TextFile2.t4
#>
TextFile1.t4:
Output Message 2 (from included file).
<#@ include file="TextFile2.t4" #>
Output Message 4 (from included file).
<#+ // Start of class feature control block.
void GenerateMessage(int n)
{
#>
Output Message <#= n #> (from GenerateMessage method).
<#+
}
#>
TextFile2.t4:
Output Message 3 (from included file 2).
<#+ // Start of class feature control block.
void AnotherGenerateMessage(int n)
{
#>
Output Message <#= n #> (from AnotherGenerateMessage method).
<#+
}
#>
Die infolge des Vorgangs generierte Datei "MyTextTemplate.txt":
Output message 1 (from top template).
Output Message 2 (from included file).
Output Message 3 (from included file 2).
Output Message 4 (from included file).
Output message 5 (from top template).
Output Message 6 (from GenerateMessage method).
Output Message 7 (from AnotherGenerateMessage method).
Verwenden von Projekteigenschaften in MSBuild und Visual Studio
Visual Studio-Makros wie „$(SolutionDir)“ können zwar in einer Include-Anweisung verwendet werden, in MSBuild jedoch nicht. Wenn Sie Vorlagen im Buildcomputer transformieren möchten, müssen Sie dies mithilfe von Projekteigenschaften tun.
Bearbeiten Sie die CSPROJ- oder VBPROJ-Datei, und definieren Sie eine Projekteigenschaft. In folgendem Beispiel wird eine Eigenschaft mit dem Namen myIncludeFolder
definiert:
<!-- Define a project property, myIncludeFolder: -->
<PropertyGroup>
<myIncludeFolder>$(MSBuildProjectDirectory)\..\libs</myIncludeFolder>
</PropertyGroup>
<!-- Tell the MSBuild T4 task to make the property available: -->
<ItemGroup>
<T4ParameterValues Include="myIncludeFolder">
<Value>$(myIncludeFolder)</Value>
</T4ParameterValues>
</ItemGroup>
Nun können Sie die Projekteigenschaft in Textvorlagen verwenden, die sowohl in Visual Studio als auch in MSBuild ordnungsgemäß transformiert werden:
<#@ include file="$(myIncludeFolder)\defs.tt" #>