2010-12-28 8 views
5

Hintergrund:T4-Textvorlage - Ist es möglich, Kompilierungssymbole vom Host zu erhalten?

Ich habe ein offenes Spiel Bibliothek Quelle in C# geschrieben, die sehr für die Leistung abgestimmt ist, unsicheren Code verwenden, Pointer-Arithmetik usw. habe ich vor kurzem die Bibliothek zu Windows Phone portiert. Leider hat Windows Phone nicht unsicheren Code unterstützen überhaupt, so habe ich zu Wurf meine Quellcode mit Präprozessordirektiven wie dies hatte:

#if WINDOWS || XBOX 
public unsafe struct Foo 
#elif WINDOWS_PHONE 
public struct Foo 
#endif 

Aufgrund der Menge dieser Richtlinien die Code-Basis geworden ist ziemlich unleserlich und schwer zu pflegen, also habe ich andere Optionen untersucht - eine davon ist Textvorlagen mit T4.

Die Frage:

Was muss ich zu weit wissen, bevor sie nach unten die T4 Route, ob ist oder nicht, ist es möglich, Zusammenstellung Symbole aus einer Textvorlage zu bekommen? Ich habe mir Template-Parameter angesehen, aber es schien nicht so einfach zu sein, sie von der Außenwelt abzuändern. Im Idealfall ist ein bisschen wie das ist etwas, was ich gerne sehen würde:

<# if (Host.CompilationSymbols.Contains("WINDOWS_PHONE") { #> 
public struct Foo 
<# { #> 

Wenn jemand etwas Licht auf, ob vergießen konnte oder nicht, das ist möglich, ich wäre dankbar!

+0

Neugierig - vorausgesetzt, Sie entfernen das unsichere Deklarationsattribut mit T4, was machen Sie mit dem tatsächlichen unsicheren Code? – tgiphil

+0

Offensichtlich ist es nicht der * einzige * Ort, an dem die Vorlage die Dinge verändern würde - andere Beispiele wären Foo * Bar ändert sich in ref Foo bar oder bar-> foo() ändert sich in bar.foo() – MattDavey

Antwort

3

Matt, Sie sind nicht verfügbar, nein, da die Kompilierung für Ihr Projekt und die Kompilierung für die Vorlagen ab VS2010 vollständig isoliert sind.

Allerdings habe ich eine (etwas ungeschickte) Abhilfe für Sie.

Wenn Sie eine Stub-Datei einschließen, die Ihre Vorlage-Direktive enthält, können Sie Compiler-Optionen mit dem entsprechenden Symbol für die Kompilierung festlegen.

z.B. eine einfache Stub der folgenden, mit dem Namen Define.t4 enthält:

<#@ template compilerOptions="/d:XBOX" debug="false" hostspecific="false" language="C#" #> 

Setzen Sie diese in einem Unterverzeichnis namens XBOX und setzt ein ähnliches in einem Verzeichnis mit dem Namen PHONE

<#@ template compilerOptions="/d:PHONE" debug="false" hostspecific="false" language="C#" #> 

Beachten Sie die Compiler Symboldefinitionen.

Jetzt eine Umgebungsvariable entweder XBOX oder Telefon Set - Architektur

nun anstelle der Vorlage-Direktive in Ihren Vorlagen sagen lassen, gehören die Define.t4 Datei und Sie werden in der Lage regelmäßig C#/VB verwenden Konditionssyntax. Vergiss nicht, das #if in die eigene Zeile zu setzen. Hier ist ein Beispiel:

<#@ include file="$(ProjectDir)%ARCHITECTURE%\Define.t4" #> 
<#@ output extension=".txt" #> 
<# 
#if XBOX #> 
public unsafe struct Foo 
<# 
#else #> 
public struct Foo 
<# 
#endif #> 

Hoffe, das bringt Sie in Bewegung.

+0

Danke Gareth! Ich hatte eine Problemumgehung, bei der ich die .csproj-Datei in meiner Vorlage analysierte und nach einem -Knoten suchte, aber Ihr Weg ist viel sauberer :) – MattDavey