Schreiben einer T4-Textvorlage

Eine Textvorlage enthält den Text, der aus ihr generiert wird. Eine Vorlage, die eine Webseite erstellt, enthält z. B. "<html>…" und alle anderen Standardteile einer HTML-Seite. In die Vorlage sind Kontrollblöcke eingefügt, bei denen es sich um Fragmente des Programmcodes handelt. Kontrollblöcke stellen veränderliche Werte bereit und ermöglichen es, Bedingungen für Teile des Texts zu definieren und Teile des Texts zu wiederholen.

Diese Struktur vereinfacht das Entwickeln einer Vorlage, da Sie mit einem Prototyp der generierten Datei beginnen und nach und nach Kontrollblöcke zum Verändern des Ergebnisses einfügen können.

Textvorlagen bestehen aus den folgenden Teilen:

  • Direktiven: Elemente, die steuern, wie die Vorlage verarbeitet wird.

  • Textblöcke: Inhalt, der direkt in die Ausgabe kopiert wird.

  • Kontrollblöcke: Programmcode, durch den Variablenwerte in den Text eingefügt und bedingte oder wiederholte Teile des Texts gesteuert werden.

Kopieren Sie die Beispiele in diesem Thema wie unter Generieren von Code zur Entwurfszeit mithilfe von T4-Textvorlagen beschrieben in eine Vorlagendatei, um sie auszuprobieren. Speichern Sie Vorlagendatei nach dem Bearbeiten, und überprüfen Sie dann die .txt-Ausgabedatei.

Direktiven

Textvorlagendirektiven stellen allgemeine Anweisungen zum Generieren des Transformationscodes und der Ausgabedatei für das Textvorlagenmodul bereit.

Die folgende Direktive gibt z. B. an, dass die Ausgabedatei die Erweiterung .txt haben soll:

<#@ output extension=".txt" #>

Weitere Informationen zu Direktiven finden Sie unter T4-Textvorlagendirektiven.

Textblöcke

Durch einen Textblock wird Text direkt in die Ausgabedatei eingefügt. Für Textblöcke wird keine spezielle Formatierung verwendet. Die folgende Textvorlage erzeugt z. B. eine Textdatei, die das Wort "Hello" enthält:

<#@ output extension=".txt" #>
Hello

Kontrollblöcke

Kontrollblöcke sind Abschnitte des Programmcodes, die zum Transformieren der Vorlagen verwendet werden. Die Standardsprache ist C#, zur Verwendung von Visual Basic können Sie jedoch die folgende Direktive am Anfang der Datei schreiben:

<#@ template language="VB" #>

Die Sprache, in der Sie den Code in den Kontrollblöcken schreiben, steht in keinem Zusammenhang mit der Sprache des generierten Texts.

Standardkontrollblöcke

Ein Standardkontrollblock ist ein Abschnitt des Programmcodes, durch den ein Teil der Ausgabedatei generiert wird.

Sie können in einer Vorlagendatei eine beliebige Anzahl von Textblöcken und Standardkontrollblöcken kombinieren. Es ist jedoch nicht möglich, einen Kontrollblock in einen anderen Kontrollblock einzufügen. Jeder Standardkontrollblock ist durch die Symbole <# ... #> begrenzt.

Beim folgenden Kontrollblock und Textblock wird z. B. die Zeile "0, 1, 2, 3, 4 Hello!" in die Ausgabedatei eingefügt:

<#
    for(int i = 0; i < 4; i++)
    {
        Write(i + ", ");
    }
    Write("4");

#> Hello!

Anstatt explizite Write()-Anweisungen zu verwenden, können Sie Text und Code verschachteln. Im folgenden Beispiel wird "Hello!" viermal gedruckt:

<#
    for(int i = 0; i < 4; i++)
    {
#>
Hello!
<#
    } 
#>

Sie können überall dort einen Textblock einfügen, wo eine Write();-Anweisung im Code zulässig wäre.

Tipp

Wenn Sie einen Textblock innerhalb einer Verbundanweisung einbetten, z. B. in einer Schleife oder Bedingung, muss der Textblock immer in geschweifte Klammern {...} gesetzt werden.

Ausdruckskontrollblöcke

Durch einen Ausdruckskontrollblock wird ein Ausdruck ausgewertet und in eine Zeichenfolge konvertiert. Diese Zeichenfolge wird in die Ausgabedatei eingefügt.

Ausdruckskontrollblöcke sind durch die Symbole <#= ... #> begrenzt.

Beim folgenden Kontrollblock enthält die Ausgabedatei z. B. "5":

<#= 2 + 3 #>

Beachten Sie, dass das Öffnungssymbol aus drei Zeichen besteht "<#=".

Der Ausdruck kann beliebige gültige Variablen enthalten. Durch den folgenden Block werden z. B. Zeilen mit Zahlen ausgegeben:

<#@ output extension=".txt" #>
<#
    for(int i = 0; i < 4; i++)
    {
#>
This is hello number <#= i+1 #>: Hello!
<#
    } 
#>

Klassenfunktionskontrollblöcke

Ein Klassenfunktionskontrollblock definiert Eigenschaften, Methoden oder anderen Code, die nicht in der Haupttransformation enthalten sein sollten. Klassenfunktionsblöcke werden häufig für Hilfsfunktionen verwendet. Normalerweise werden Klassenfunktionsblöcke in separaten Dateien gespeichert, damit sie in mehrere Textvorlagen eingeschlossen werden können.

Klassenfunktionskontrollblöcke sind durch die Symbole <#+ ... #> begrenzt.

In der folgenden Vorlagendatei wird z. B. eine Methode deklariert und verwendet:

<#@ 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;
}
#>

Klassenfunktionen müssen am Ende der Datei eingefügt werden, in der sie geschrieben werden. <#@include#> kann jedoch auch dann für eine Datei, die eine Klassenfunktion enthält, verwendet werden, wenn nach der include-Direktive Standardblöcke und Text eingefügt werden.

Weitere Informationen zu Kontrollblöcken finden Sie unter Kontrollblöcke für T4-Textvorlagen.

Klassenfunktionsblöcke können Textblöcke enthalten

Sie können eine Methode schreiben, durch die Text generiert wird. Beispiel:

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 #>.
<#   
}
#>

Es ist sinnvoll, Methoden zum Generieren von Text in einer separaten Datei zu speichern, die in mehrere Vorlagen eingeschlossen werden kann.

Verwenden von externen Definitionen

Assemblys

In den Codeblöcken der Vorlage können Typen verwendet werden, die in den am häufigsten verwendeten .NET-Assemblys definiert sind, z. B. System.dll. Außerdem können Sie auf andere .NET-Assemblys oder eigene Assemblys verweisen. Sie können einen Pfadnamen oder den starken Namen einer Assembly angeben:

<#@ assembly name="System.Xml" #>

Verwenden Sie absolute Pfadnamen oder standardmäßige Makronamen im Pfadnamen. Beispiel:

<#@ assembly name="$(SolutionDir)library\MyAssembly.dll" #>

Eine Liste der Makros finden Sie unter Makros für Buildbefehle und -eigenschaften.

Die assembly-Direktive hat in einer vorverarbeiteten Textvorlage keinerlei Auswirkungen.

Weitere Informationen finden Sie unter T4-Assemblydirektive.

Namespaces

Die import-Direktive entspricht der using-Klausel in C# bzw. der imports-Klausel in Visual Basic. Sie ermöglicht es Ihnen, ohne einen vollqualifizierten Namen auf Typen im Code zu verweisen:

<#@ import namespace="System.Xml" #>

Sie können beliebig viele assembly- und import-Direktiven verwenden. Diese Direktiven müssen vor Text- und Kontrollblöcken eingefügt werden.

Weitere Informationen finden Sie unter T4-Import-Direktive.

Einschließen von Code und Text

Die include-Direktive fügt Text aus einer anderen Vorlagendatei ein. Die folgende Direktive fügt z. B. den Inhalt von test.txt ein.

<#@ include file="c:\test.txt" #>

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 der include-Direktive normale Text- und Standardkontrollblöcke eingefügt werden.

Weitere Informationen finden Sie unter T4-Include-Direktive.

Hilfsmethoden

Mehrere Methoden wie z. B. Write() stehen Ihnen in einem Kontrollblock immer zur Verfügung. Dazu zählen Methoden zum Einziehen der Ausgabe und Melden von Fehlern.

Sie können auch einen eigenen Satz von Hilfsmethoden schreiben.

Weitere Informationen finden Sie unter Hilfsmethoden für T4-Textvorlagen.

Transformieren von Daten und Modellen

Einer der sinnvollsten Verwendungszwecke von Textvorlagen ist das Generieren von Material basierend auf dem Inhalt einer Quelle, z. B. einem Modell, einer Datenbank oder einer Datendatei. Die Vorlage extrahiert Daten und formatiert sie neu. Durch eine Auflistung von Vorlagen kann eine solche Quelle in mehrere Dateien transformiert werden.

Zum Lesen der Quelldatei sind mehrere Ansätze verfügbar.

Lesen einer Datei in der Textvorlage. Dies ist einfachste Methode, um Daten in die Vorlage abzurufen:

<#@ import namespace="System.IO" #>
<# string fileContent = File.ReadAllText(@"C:\myData.txt"); ...

Laden einer Datei als navigierbares Modell. Eine effektivere Methode besteht darin, die Daten als ein Modell zu lesen, durch das der Textvorlagencode navigieren kann. Sie können z. B. eine XML-Datei laden und mit XPath-Ausdrücken darin navigieren. Sie können auch mithilfe von xsd.exe einen Satz von Klassen erstellen, mit denen die XML-Daten gelesen werden können.

Bearbeiten der Modelldatei in einem Diagramm oder Formular. Die Domänenspezifische Sprachtools stellen Tools bereit, mit denen ein Modell als Diagramm oder Windows Form bearbeiten werden kann. Dadurch kann das Modell einfacher mit Benutzern der generierten Anwendung besprochen werden. Die Domänenspezifische Sprachtools erstellen auch einen Satz stark typisierter Klassen, die die Struktur des Modells wiedergeben. Weitere Informationen finden Sie unter Generieren von Code für eine domänenspezifische Sprache.

Verwenden eines UML-Modells. Sie können Code aus einem UML-Modell generieren. Dies hat den Vorteil, dass das Modell als Diagramm in einer gewohnten Darstellungsweise bearbeitet werden kann. Zudem müssen Sie das Diagramm nicht entwerfen. Weitere Informationen finden Sie unter Gewusst wie: Generieren von Dateien aus einem UML-Modell.

Relative Dateipfade

Wenn Sie auf eine Datei an einem Ort verweisen möchten, der relativ zur Textvorlage ist, verwenden Sie this.Host.ResolvePath(). Sie müssen auch hostspecific="true" in der template-Direktive festlegen:

<#@ 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 #>

Sie können auch andere Dienste empfangen, die vom Host bereitgestellt werden. Weitere Informationen finden Sie unter Zugreifen auf Visual Studio oder andere Hosts von einer T4-Textvorlage.

In einer separaten AppDomain ausgeführte Textvorlagen

Eine Textvorlage wird in einer AppDomain ausgeführt wird, die von der Hauptanwendung getrennt ist. In den meisten Fällen ist dies nicht wichtig, doch in bestimmten komplexen Fällen können sich Einschränkungen ergeben. Wenn Sie z. B. Daten in oder aus der Vorlage von einem separaten Dienst übergeben möchten, muss der Dienst eine serialisierbare API bereitstellen.

Bearbeiten von Vorlagen

Spezialisierte Textvorlagen-Editoren können aus dem Onlinekatalog des Erweiterungs-Managers heruntergeladen werden. Klicken Sie im Menü Extras auf Erweiterungs-Manager. Klicken Sie auf Onlinekatalog, und verwenden Sie dann das Suchtool.

Verwandte Themen

Aufgabe

Thema

Schreiben einer Textvorlage.

Richtlinien für das Verfassen von T4-Textvorlagen

Generieren Sie Text mithilfe von Programmcode.

Schreiben einer T4-Textvorlage

Generieren Sie Dateien in einer Visual Studio-Projektmappe.

Generieren von Code zur Entwurfszeit mithilfe von T4-Textvorlagen

Führen Sie die Textgenerierung außerhalb von Visual Studio aus.

Generieren von Dateien mit dem Hilfsprogramm "TextTransform"

Transformieren Sie die Daten in das Format einer domänenspezifischen Sprache.

Generieren von Code für eine domänenspezifische Sprache

Schreiben Sie Direktivenprozessoren, um eigene Datenquellen zu transformieren.

Anpassen der T4-Texttransformation

Änderungsprotokoll

Datum

Versionsgeschichte

Grund

März 2011

Verwendung von Makros in Assemblydirektive.

Kundenfeedback.