Laden...

T4-Skript zur Code-Generierung für übersetzbare Texte

Erstellt von Sarc vor 12 Jahren Letzter Beitrag vor 12 Jahren 4.618 Views
S
Sarc Themenstarter:in
417 Beiträge seit 2008
vor 12 Jahren
T4-Skript zur Code-Generierung für übersetzbare Texte

Das beigefügte T4-Skript ist als Ersatz für den ResXFileCodeGenerator gedacht (nur für Strings, keine anderen Resourcen wie Bilder etc.), welcher anhand von Resx-Dateien Quellcode erzeugt. Das T4-Skript lässt sich im Gegensatz zum ResXFileCodeGenerator leicht anpassen.

Hintergrund:
Der bevorzugte Weg um eine .NET Anwendung übersetzbar zu gestalten führt über Resourcen / Resx-Dateien. Anhand der Daten einer Resx-Dateien, erzeugt das standardmäßige Custom Tool ResXFileCodeGenerator eine Resourcen-Klasse, über die der Zugriff auf die übersetzbaren Texte möglich ist.

Schwachstelle des ResXFileCodeGenerator:
Leider bietet der ResXFileCodeGenerator keine Eingriffsmöglichkeiten in den generierten Quelltext und ist somit nicht erweiterbar. An manchen Stellen (z.B. in Attributen) muss man manchmal den Namen eines zu übersetzenden Wertes angeben, wie beispielsweise hier (Name = "Password"):

[Display(ResourceType=typeof(Strings), Name = "Password")]
public string Password { get; set; }

Das ist fehleranfällig, da eine Änderung des Namens in der Resourcendatei nicht festgestellt werden kann und zur Laufzeit einen Fehler erzeugt.

Ok, jetzt zum T4-Skript:
Wer (noch) nicht weiss, was T4 ist, der kann sich hier ein wenig informieren: T4 (Text Template Transformation Toolkit) Code Generation - Best Kept Visual Studio Secret

Allen T4-Dateien (*.tt) ist standardmäßig das Custom Tool TextTemplatingFileGenerator zugewiesen. Normalerweise
können diese Dateien über den Contextmenüpunkt "Run Custom Tool" ausgeführt werden. Da wir jedoch nicht immer manuell
die Generierung anstossen möchten, verwenden wir das Custom Tool T4ScriptFileGenerator.
Hierfür wird zusätzlich das T4-Toolbox benötigt, welches hier runtergeladen werden kann: http://t4toolbox.codeplex.com/

Das Custom tool T4ScriptFileGenerator wird dann der *.resx-Datei als Custom Tool zugewiesen, d.h. es ersetzt das standardmäßige custom tool ResXFileCodeGenerator. Dadurch wird nach jeder Speicherung der *.resx-Datei die Code Generierung des T4-Skripts angestossen.

Das ganze sieht dann im Solution Explorer etwa wie folgt aus, wobei Strings.tt hier das eigentliche T4-Skript ist (wichtig ist das die Namen identisch sind, also Strings.tt/Strings.resx):
-> siehe nächster Post

Ein Beispielprojekt, inklusive des T4-Skripts (Strings.tt) ist unten angefügt.
Wie dort zu erkennen ist, erstellt das Skript zusätzlich eine Klasse (Name ist konfigurierbar), welche die Namen der Resourcen enthält:

public static partial class ResourceNames
{
       	public const string FileNotFound = "FileNotFound";
       	public const string Title = "Title";
       	public const string Today = "Today";
}

Auf diese Werte kann im Anwendungscode verwiesen werden. Da diese bei jeder Änderung neu erzeugt werden, sind Änderungen sofort zu Compilezeit feststellbar.

Ein weiteres Feature ist die Unterstützung von Formatierungsparametern in der Resourcendatei. Normalerweise lassen sich übersetzbare Parameter im Text etwa wie folgt schreiben:

Die Datei '{0}' wurde nicht gefunden.

Der Anwendungscode ruft dann meist string.Format mit den entsprechenden Parametern auf.
Das T4-Skript nimmt einen gewissen Teil dieser Arbeit ab. Und zwar können spezielle Parameter im Text definiert werden,
welche vom T4-Skript entsprechend interpretiert werden. Das Format ist: {t:n} wobei t für den Typ des Parameters und n für den Namen steht. t ist optional, d.h. wenn t nicht angegeben wird ({:n}), dann wird als Typ des Parameters object gesetzt. Obiger Text könnte also so geschrieben werden:

Die Datei '{s:filename}' wurde nicht gefunden.

Das 's' steht für den Typ string. Das T4-Skript erzeugt dann daraus keine Eigenschaft, sondern eine Methode mit den entsprechenden Parametern. In diesem Fall eine Methode mit dem Parameter 'filename' vom Typen string:

/// <summary>
/// Die Datei '{s:filename}' wurde nicht gefunden.
/// </summary>
public static string FileNotFound(string filename, IFormatProvider formatProvider = null)
{
	...
}

Die generierte Klasse heisst in dem Beispiel Strings, daher könnte die obige Methode wie folgt aufgerufen werden:

Strings.FileNotFound("test.txt")

Ich hoffe jemand kann damit was anfangen 😃

Schlagwörter: T4, Resx, Resourcen, Übersetzung, Generator

S
Sarc Themenstarter:in
417 Beiträge seit 2008
vor 12 Jahren

Hier das Bild.