Richtlinien für das Verfassen von T4-Textvorlagen
Die folgenden allgemeinen Richtlinien können beim Generieren von Programmcode oder anderen Anwendungsressourcen in Visual Studio hilfreich sein.Es handelt sich hierbei nicht um feste Regeln.
Richtlinien für Entwurfszeit-T4-Vorlagen
Entwurfszeit-T4-Vorlagen sind Vorlagen, die zur Entwurfszeit Code im Visual Studio-Projekt generieren.Weitere Informationen finden Sie unter Generieren von Code zur Entwurfszeit mithilfe von T4-Textvorlagen.
Generieren Sie variable Teile der Anwendung.
Die Codegenerierung eignet sich am besten für die Teile der Anwendung, die sich während des Projekts oder zwischen unterschiedlichen Versionen der Anwendung ändern können.Trennen Sie diese variablen Teile von den weniger veränderlichen Teilen, damit Sie leichter feststellen können, was generiert werden muss.Wenn die Anwendung z. B. eine Website bereitstellt, trennen Sie die standardmäßigen Seitenverarbeitungsfunktionen von der Logik, die die Navigationspfade zwischen den einzelnen Seiten definiert.Codieren Sie die variablen Teile in einem oder mehreren Quellmodellen.
Ein Modell ist eine Datei oder eine Datenbank, die von jeder Vorlage gelesen wird, um bestimmte Werte für variable Teile des zu generierenden Codes abzurufen.Modelle können Datenbanken, selbst entworfene XML-Dateien, Diagramme oder domänenspezifische Sprachen sein.In der Regel wird ein Modell verwendet, um zahlreiche Dateien in einem Visual Studio-Projekt zu generieren. Jede Datei wird von einer separaten Vorlage generiert.Sie können in einem Projekt mehrere Modelle verwenden.Sie können z. B. ein Modell für die Navigation zwischen Webseiten und ein separates Modell für das Layout der Seiten definieren.
Richten Sie das Modell auf die Anforderungen und das Vokabular der Benutzer aus, nicht auf die Implementierung.
In einer Websiteanwendung würde z. B. erwartet werden, dass das Modell auf Webseiten und Links verweist.Wählen Sie idealerweise eine Darstellungsform aus, die sich für die vom Modell dargestellten Informationen eignet.Für ein Modell von Navigationspfaden durch eine Website kann z. B. ein Diagramm mit Feldern und Pfeilen verwendet werden.
Testen Sie den generierten Code.
Verwenden Sie manuelle oder automatisierte Tests, um zu überprüfen, ob der aus dem Vorgang resultierende Code gemäß den Benutzeranforderungen funktioniert.Vermeiden Sie, Tests mit dem gleichen Modell zu generieren, mit dem auch der Code generiert wird.In einigen Fällen können allgemeine Tests direkt für das Modell ausgeführt werden.Sie können z. B. einen Test schreiben, durch den sichergestellt wird, dass jede Seite der Website mittels Navigation von anderen Seiten aus erreichbar ist.
Zulassen von benutzerdefiniertem Code: Generieren von partiellen Klassen.
Verwenden Sie neben dem generierten Code manuell erstellten Code.Ein Codegenerierungsschema kann nur in seltenen Fällen alle möglichen Variationen abdecken, die auftreten können.Es ist daher zu erwarten, dass Code hinzugefügt werden muss oder Teile des generierten Codes überschrieben werden müssen.Wen das generierte Material in einer .NET-Sprache wie Visual C# oder Visual Basic vorliegt, sind zwei Strategien besonders hilfreich:Die generierten Klassen sollten partiell sein.Auf diese Weise können Sie dem generierten Code Inhalt hinzufügen.
Klassen sollten paarweise generiert werden, wobei eine Klasse von der anderen erbt.Die Basisklasse sollte alle generierten Methoden und Eigenschaften enthalten und die abgeleitete Klasse nur die Konstruktoren.So können generierte Methoden durch handgeschriebenen Code überschrieben werden.
Verwenden Sie in anderen generierten Sprachen wie XML die <#@include#>-Direktive, um einfache Kombinationen aus handgeschriebenen und generierten Inhalten zu erstellen.In komplexeren Fällen müssen Sie möglicherweise einen Nachverarbeitungsschritt schreiben, durch den die generierte Datei mit handgeschriebenen Dateien kombiniert wird.
Verschieben von allgemeinem Material in Includedateien oder Laufzeitvorlagen
Um zu vermeiden, dass ähnliche Textblöcke und Code in mehreren Vorlagen wiederholt werden, verwenden Sie die <#@ include #>-Direktive.Weitere Informationen finden Sie unter T4-Include-Direktive.Sie können auch Laufzeittextvorlagen in einem separaten Projekt erstellen und sie anschließend mit der Entwurfszeitvorlage aufrufen.Verwenden Sie hierzu die <#@ assembly #>-Direktive, um auf das separate Projekt zuzugreifen.Beispiele finden Sie unter "Vererbung in Textvorlagen" im Blog von Gareth Jones.
Verschieben Sie ggf. große Codeblöcke in eine separate Assembly.
Wenn Sie über große Code- und Klassenfunktionsblöcke verfügen, könnte es hilfreich sein, einen Teil des Codes in Methoden zu verschieben, die Sie in einem separaten Projekt kompilieren.Sie können mithilfe der <#@ assembly #>-Direktive auf den Code in der Vorlage zugreifen.Weitere Informationen finden Sie unter T4-Assemblydirektive.Sie können die Methoden in eine abstrakte Klasse einfügen, die die Vorlage erben kann.Die abstrakte Klasse muss von Microsoft.VisualStudio.TextTemplating.TextTransformation erben.Weitere Informationen finden Sie unter T4-Vorlagendirektive.
Generieren von Code (keine Konfigurationsdateien)
Eine Methode zum Schreiben einer variablen Anwendung besteht darin, generischen Programmcode zu schreiben, der eine Konfigurationsdatei akzeptiert.Eine auf diese Weise geschriebene Anwendung ist sehr flexibel und kann bei Veränderungen der Geschäftsanforderungen neu konfiguriert werden, ohne die Anwendung neu zu erstellen.Ein Nachteil dieses Ansatzes ist jedoch, dass die Anwendung weniger Leistung bietet als eine spezifischere Anwendung.Zudem ist der Programmcode schwieriger zu lesen und zu verwalten. Dies ist teilweise darauf zurückzuführen, dass die generischsten Typen verwendet werden müssen.Eine Anwendung, deren variable Teile vor der Kompilierung generiert werden, kann dagegen stark typisiert werden.Dadurch kann handgeschriebener Code einfacher und zuverlässiger erstellt und in die generierten Teile der Software integriert werden.
Versuchen Sie anstelle von Konfigurationsdateien Programmcode zu generieren, um die Vorteile der Codegenerierung optimal nutzen zu können.
Verwenden eines generierten Codeordners
Speichern Sie die Vorlagen und generierten Dateien in einem Projektordner mit dem Namen "Generierter Code", um deutlich zu machen, dass diese Dateien nicht direkt bearbeitet werden sollten.Wenn Sie benutzerdefinierten Code erstellen, durch den die generierten Klassen überschrieben werden sollen oder der ihnen hinzugefügt werden soll, speichern Sie diese Klassen in einem Ordner mit dem Namen "Benutzerdefinierter Code".Das folgende Beispiel zeigt die Struktur eines typischen Projekts:MyProject Custom Code Class1.cs Class2.cs Generated Code Class1.tt Class1.cs Class2.tt Class2.cs AnotherClass.cs
Richtlinien für Laufzeit-T4-Vorlagen (vorverarbeitete Vorlagen)
Verschieben von allgemeinem Material in geerbte Vorlagen
Sie können Methoden und Textblöcke mithilfe von Vererbung zwischen T4-Textvorlagen freigeben.Weitere Informationen finden Sie unter T4-Vorlagendirektive.Sie können auch Dateien einschließen, die über Laufzeitvorlagen verfügen.
Verschieben von umfangreichem Codetext in eine partielle Klasse.
Jede Laufzeitvorlage generiert eine Definition für eine partiellen Klasse, die den gleichen Namen wie die Vorlage besitzt.Sie können eine Codedatei schreiben, die eine andere partielle Definition der gleichen Klasse enthält.Sie können der Klasse auf diese Weise Methoden, Felder und Konstruktoren hinzufügen.Diese Member können von den Codeblöcken in der Vorlage aufgerufen werden.Ein Vorteil dieser Methode besteht darin, dass der Code einfacher zu schreiben ist, da IntelliSense verfügbar ist.Außerdem erzielen Sie eine bessere Trennung zwischen der Präsentation und der zugrunde liegenden Logik.
Zum Beispiel in MyReportText.tt:
The total is: <#= ComputeTotal() #>
In MyReportText-Methods.cs:
private string ComputeTotal() { ... }
Zulassen von benutzerdefiniertem Code: Bereitstellen von Erweiterungspunkten
Generieren Sie ggf. virtuelle Methoden in < #+ Klassenfunktionsblöcken #>.Dies ermöglicht in vielen Zusammenhängen die Verwendung einer einzigen Vorlage ohne zusätzlichen Änderungsbedarf.Anstatt die Vorlage zu ändern, können Sie eine abgeleitete Klasse erstellen, die die minimale zusätzliche Logik bereitstellt.Bei der abgeleiteten Klasse kann es sich entweder um regulären Code oder um eine Laufzeitvorlage handeln.Zum Beispiel in "MyStandardRunTimeTemplate.tt":
This page is copyright <#= CompanyName() #>. <#+ protected virtual string CompanyName() { return ""; } #>
Im Code einer Anwendung:
class FabrikamTemplate : MyStandardRunTimeTemplate { protected override string CompanyName() { return "Fabrikam"; } } ... string PageToDisplay = new FabrikamTemplate().TextTransform();
Richtlinien für alle T4-Vorlagen
Trennen der Datensammlung von der Textgenerierung
Kombinieren Sie nach Möglichkeit keine Berechnungs- und Textblöcke miteinander.Verwenden Sie in jeder Textvorlage den ersten < #Codeblock #>, um Variablen festzulegen und komplexe Berechnungen auszuführen.Vermeiden Sie vom ersten Textblock bis zum Ende der Vorlage oder des ersten < #+ Klassenfunktionsblocks #> lange Ausdrücke und Schleifen sowie Bedingungen, sofern Sie keine Textblöcke enthalten.Dadurch werden Lesbarkeit und Verwaltung der Vorlage erleichtert.Verwenden Sie nicht .tt für Includedateien.
Verwenden Sie eine andere Dateinamenerweiterung wie z. B. .ttinclude für Includedateien.Verwenden Sie .tt nur für Dateien, die Sie entweder als Laufzeit- oder Entwurfszeittextvorlagen verarbeiten möchten.In einigen Fällen erkennt Visual Studio .tt-Dateien und legt ihre Eigenschaften automatisch zur Verarbeitung fest.Beginnen Sie jede Vorlage mit einem festen Prototyp.
Schreiben Sie ein Beispiel des Codes oder Texts, den Sie generieren möchten, und vergewissern Sie sich, dass er korrekt ist.Ändern Sie dann die Erweiterung in .tt, und fügen Sie nach und nach Code ein, der den Inhalt durch das Lesen des Modells ändert.Verwenden Sie ggf. typisierte Modelle.
Obwohl Sie ein XML oder ein Datenbankschema für die Modelle erstellen können, kann es hilfreich sein, eine domänenspezifische Sprache (DSL) zu erstellen.Eine domänenspezifische Sprache hat den Vorteil, dass sie eine Klasse generiert, die jeden Knoten im Schema darstellt, und Eigenschaften, die die Attribute darstellen.Dies bedeutet, dass Sie Programmierschritte entsprechend dem Geschäftsmodell ausführen können.Beispiele:Team Members: <# foreach (Person p in team.Members) { #> <#= p.Name #> <# } #>
Verwenden Sie ggf. Diagramme für die Modelle.
Zahlreiche Modelle können in Form von Texttabellen am effektivsten präsentiert und verwaltet werden, insbesondere, wenn sie sehr groß sind.Bei einigen Geschäftsanforderungen ist es jedoch wichtig, komplexe Beziehungen und Workflows zu veranschaulichen. Diagramme eignen sich hierfür am besten.Ein Vorteil eines Diagramms liegt darin, dass problemlos mit Benutzern und anderen Projektbeteiligten diskutiert werden kann.Durch Generieren von Code mithilfe eines Modells auf der Ebene der Geschäftsanforderungen gewinnt der Code bei sich ändernden Anforderungen an Flexibilität.
UML-Klassen- und Aktivitätsdiagramme können oft zu diesen Zwecken angepasst werden.Sie können auch einen eigenen Diagrammtyp als domänenspezifische Sprache (DSL) entwerfen.Code kann sowohl mit UML als auch mit DSLs generiert werden.Weitere Informationen finden Sie unter Modellieren der Anwendung und Modellieren der Anwendung.
Siehe auch
Konzepte
Generieren von Code zur Entwurfszeit mithilfe von T4-Textvorlagen