2010-02-21 4 views
20

Wir erstellen eine Inhouse-Anwendung, die HTML-Dateien zum Hochladen in eBay-Angebote generieren muss. Wir versuchen, eine Template-Engine zu verwenden, um die HTML-Dateien basierend auf von uns vordefinierten Datenbank- und statischen Feldern zu generieren. Die Vorlage muss auch Logikfähigkeiten haben (wenn-dann, foreach, usw.). Wir haben uns T4 angeschaut und es sieht perfekt aus, aber wir sehen nichts darüber, ob es die Fähigkeiten hat, zur Laufzeit verwendet zu werden, so dass ein Benutzer die T4-Vorlage erstellen kann, und dann kann die Anwendung "kompilieren" "Es und generieren Sie die endgültige HTML-Datei. Ist das möglich und wie?T4 Templates zur Laufzeit erstellen (Build-Time)?

Wenn nicht, gibt es andere Rahmen, die wir betrachten sollten, die all diese Fähigkeiten haben?

Antwort

16

Ich habe eine ähnliche Reihe von Klassen, die ich dafür verwende, Template-Texterzeugung in Software eingebettet.

Grundsätzlich funktioniert es wie altmodischer ASP, Sie umgeben C# -Code in <%...%> Blöcke, und Sie können Ergebnisse ausgeben, indem Sie <%= expression %> verwenden.

Sie können ein einzelnes Objekt in den Template-Code übergeben, die natürlich jeder Objekttyp sein, die Sie mögen, oder einfach eine Reihe von Parametern. Sie können auch auf Ihre eigenen Assemblies verweisen, wenn Sie benutzerdefinierten Code ausführen möchten.

Hier ist, wie eine Klasse emittierende aussehen:

<% 
var parameters = (string[])data; 
var namespaceName = parameters[0]; 
var className = parameters[1]; 
%> 
namespace <%= namespaceName %> 
{ 
    public class <%= className %> 
    { 
    } 
} 

Sie können natürlich eine Schleife durch Dinge:

<% foreach (var parameter in parameters) { %> 
<%= parameter %> 
<% } %> 

und setzen Code in if-Blöcke usw.

Die Klassenbibliothek ist auf CodePlex hier freigegeben:

sowie NuGet.

Das Projekt kommt mit Beispielen, laden Sie die Quelle oder browse it online.

Um auch hier Fragen per E-Mail zu beantworten, für andere zu sehen:

  1. Alle Arten von C# -Code die in einen Methodenaufruf paßt in der Vorlage erstellt werden. Es läuft normaler C# 3.5-Code, mit allem, was bedeutet, dass es keine künstlichen Grenzen gibt. Nur Dinge zu wissen ist, dass alle, wenn, während, für, foreach, etc. Code, der Vorlage Code enthält, um Klammern zu verwenden, können Sie nicht eine einzeilige Wenn-dann-Typ-Block. Siehe unten für die Methodenaufrufbegrenzung.
  2. Der Parameter data entspricht dem, was in Ihrer Anwendung als Parameter für die Methode .Generate(x) übergeben wurde, und ist vom gleichen Typ. Wenn Sie ein Objekt übergeben, das Sie in Ihren eigenen Klassenbibliotheken definiert haben, müssen Sie einen Verweis auf den Vorlagencode hinzufügen, um ordnungsgemäß darauf zugreifen zu können.(<%@ reference your.class.library.dll %>)
  3. Wenn Sie die kompilierte Vorlage wiederverwenden, wird es nur im Wesentlichen zu einer Klasse ein Methodenaufruf, kein zusätzlicher Aufwand auf dem tatsächlichen Aufruf .Generate() getan. Wenn Sie .Compile() nicht selbst anrufen, wird der erste Anruf an .Generate() dafür sorgen. Beachten Sie außerdem, dass der Code in einer separaten Anwendungsdomäne ausgeführt wird, sodass ein geringer Aufwand für das Marshalling im Zusammenhang mit dem Kopieren des Parameters und des Ergebnisses besteht. Der Code wird jedoch mit normaler JITted .NET-Code-Geschwindigkeit ausgeführt.

Beispiel if-Block:

<% if (a == b) { %> 
This will only be output if a==b. 
<% } %> 

gibt es keine künstlichen Grenzen den Code entweder auf die Formatierung, den Stil auswählen, die Ihnen am besten passt:

<% 
    if (a == b) 
    { 
%> 
This will only be output if a==b. 
<% 
    } 
%> 

beachten Sie nur, dass alle Nicht- Code-Teile der Vorlage werden so ziemlich ausgegeben wie sie sind, was bedeutet, dass Tabs und solche folgenden %> Blöcke ebenfalls ausgegeben werden.

Es gibt eine Grenze, den ganzen Code, den Sie in einem einzigen Methodenaufruf passen schreiben müssen.

Lassen Sie mich erklären.

Die Art und Weise der Template-Engine funktioniert, ist, dass es eine CS-Datei erzeugt und führt es dem C# -Compiler, diese CS-Datei sieht roughyly wie folgt aus:

using directives 

namespace SomeNamespace 
{ 
    public class SomeClass 
    { 
     public string Render(object data) 
     { 
      ... all your code goes here 
     } 
    } 
} 

Das bedeutet, dass Sie keine neuen Klassen definieren , neue Methoden, Klasse-Ebene Felder etc.

Sie können jedoch verwenden anonyme Delegaten Funktionen intern zu erstellen. Zum Beispiel, wenn Sie wollen, eine einheitliche Art und Weise Formatierungsdaten:

Func<DateTime, string> date2str = delegate(DateTime dt) 
{ 
    return dt.ToString("G"); 
}; 

dann können Sie einfach die Verwendung in den Rest der Template-Code:

<%= date2str(DateTime.Now) %> 

Einzige Voraussetzung ist, dass ich Sie don‘ t lade die Dateien ins Web hoch und behaupte, du hättest den Code geschrieben, außer dass du damit frei machen kannst, was du willst.

Bearbeiten 23.04.2011: Feste Verknüpfungen zum CodePlex-Projekt.

+0

Wooow O.o Ich lade dies gerade jetzt und ich werde Sie wissen lassen, wie es geht. Wenn es alles tut, was du sagst, ist es ein absoluter Lebensretter! – Amberite

+0

Bearbeitete die Antwort jetzt, wie Sie in der E-Mail sagten, die Variable "Data" existiert nicht, weil sie "Daten" genannt wird. Es ist ein Methodenparameter, daher der Kleinbuchstabe "d". –

+0

"Die Funktionsweise der Template-Engine besteht darin, dass sie eine CS-Datei erzeugt und sie dem C# -Compiler zuführt": Bedeutet das nicht auch, dass auf dem Rechner VisStudio oder zumindest etwas anderes installiert sein muss? Oder gibt es eine Möglichkeit, den C# -Compiler programmatisch aufzurufen? Ich dachte nicht, dass der Compiler mit der .NET-Laufzeitumgebung ausgeliefert wurde ... Obwohl IIS ASP.NET im laufenden Betrieb kompilieren kann, muss es irgendwo da draußen sein ... – CodingWithSpike

3

die T4-Vorlagen können mit dem TextTransform.exe Befehlszeilenprogramm kompiliert werden. Sie könnte Ihre Anwendung erstellen eine. Tt-Datei, dann rufen Sie TextTransform.exe, um die Ausgabe zu generieren.

+0

Muss Visual Studio nicht mit dieser Lösung auf dem Computer des Benutzers installiert werden? Dies ist eine Einschränkung für uns. – Amberite

+0

Mono hat eine ziemlich gute Textumwandlungsimplementierung. Ich würde mir das ansehen, wenn Abhängigkeiten ein Problem sind. –

+2

Ja, im Moment ist es eine Abhängigkeit von Visual Studio. Dies wird sich mit VS2010/.NET 4 und den so genannten vorkompilierten T4-Templates ändern. Siehe hier für Informationen: http://www.olegsych.com/2009/09/t4-preprocessed-text-templates/ –

6

Die Baugruppe, die T4-Text Transformation implementiert ist Microsoft.VisualStudio.TextTemplating.dll, die mit Visual Studio.

Wenn Sie von den ersten Prinzipien starten möchten, müssen Sie Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost implementieren und Ihre Implementierung davon als Argument an Microsoft.VisualStudio.TextTemplating.Engine.ProcessTemplate() übergeben, die die Transformation durchführen wird.

Dies gibt Ihnen mehr Flexibilität als den Aufruf von TextTransform.exe.

Allerdings, wenn Ihr Code ein Versand Produkt ist, ist es unklar, was die Lizenzierung dieser Versammlung ist, und ob Sie die Rechte es mit Ihrer Anwendung zu verteilen.

Durch die Neuverteilung dieser Assembly ist die Installation von Visual Studio nicht erforderlich.

+0

Leider ist dies nicht unsere Bedürfnisse erfüllen, weil der Lizenz Problem, da dieses Produkt an Endverbraucher werden versendet. Dank sowieso :) – Amberite

+1

Es gibt auch eine Open-Source-Implementierung durch das Projekt Mono. http://anonsvn.mono-project.com/viewvc/trunk/monodevelop/main/src/addins/TextTemplating/ –

3

Es ist durchaus möglich, T4 zur Laufzeit zu verwenden.

Microsoft unterstützt dieses Szenario nicht wirklich in .NET 3.5. Es klingt wie .NET 4.0 wird besser von Microsoft unterstützt.

Mono bietet einige Unterstützung für dieses Szenario in .NET 3.5.

Ich habe dieses Konzept mit .NET 3.5 mit Hilfe der Mono T4-Implementierung erfolgreich getestet, aber eine Standardlösung für dieses Problem für .NET 3.5 würde einen größeren Aufwand erfordern, als ich bisher investiert habe.

Sie können die Mono T4 Implementierung finden Sie hier:

https://github.com/mono/monodevelop/tree/master/main/src/addins/TextTemplating

Ich habe einige der Fragen dokumentiert ich T4-Vorlagen von .NET-Code angetroffenen versuchen, hier zu laufen:

Options for running T4 templates from .NET code

14

Wenn Sie Visual Studio 2010 zum Erstellen und Bearbeiten von Vorlagen verwenden können, können Sie vorkompilierte Vorlagen verwenden, die genau für dieses Szenario entwickelt wurden und von Microsoft unterstützt werden.

Sie entwerfen die Vorlage in Visual Studio, kompilieren sie vor und stellen eine Assembly bereit, die keine Abhängigkeiten zu Visual Studio mit Ihrer Anwendung aufweist.

http://www.olegsych.com/2009/09/t4-preprocessed-text-templates/

0

Ein Fehler, den ich gemacht, das ich eine „Textvorlagen“ Datei hinzugefügt. Um Text unter Laufzeit zu generieren, wählen Sie stattdessen die "vorverarbeitete Textvorlage". Wenn Sie ursprünglich "Textvorlage" ausgewählt haben, ist es eine einfache Änderung, das benutzerdefinierte Werkzeug in den Dateieigenschaften in VS auf "TextTemplatingFilePreprocessor" zu setzen.