2014-07-25 7 views
6

Ich möchte meine eigene Klasse definieren in einer CS-Datei in meinem TT verwenden.T4 - TT - Verwenden von benutzerdefinierten Klassen in TT-Dateien

Beispiel:

public class ClassDefinition 
{ 
    public string NameSpace { get; set; } 
    public string Name { get; set; } 
    public string Protection { get; set; } 

    List<ClassProperty> Properties { get; set; } 
} 

Mein TT wie folgt aussieht:

<#@ template debug="true" hostspecific="true" language="C#" #> 
<#@ output extension=".cs" #> 

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

<#@ import namespace="System.Xml" #> 
<#@ import namespace="System.Linq" #> 
<#@ import namespace="System.Text" #> 
<#@ import namespace="System.Collections.Generic" #> 
<#@ import namespace="System.IO" #> 

<#@ include file="$(ProjectDir)ClassDefinition.cs" #> 

<# 

// Read the model file 
XmlDocument doc = new System.Xml.XmlDocument(); 
doc.Load(this.Host.ResolvePath("GeneratedXmlFile.xml")); 

IList<XmlNode> nodeList = new List<XmlNode>(); 
foreach (XmlNode node in doc.DocumentElement) 
{ 
    switch(node.Name) 
    { 
     case "Model": 
     { 
      ClassDefinition classDefinition = new ClassDefinition(); 

Aber ich habe diese Fehlermeldung:

Compiling transformation: The type or namespace name 'ClassDefinition' could not be found (are you missing a using directive or an assembly reference?) 

ich im Internet geprüft und versucht zu: - Einsatz Verwenden Sie - verwenden Sie die Baugruppe - verwenden Sie USING Aber nichts funktioniert.

Irgendwelche Ideen?

+0

Diese wie eine offensichtliche Frage scheinen mag, aber Ihre ClassDefinition.cs im selben Projekt als * .tt Datei-Datei? – Thundter

+0

Ja, es ist im selben Projekt! – Eagle

+0

Warum verschieben Sie das ClassDefinition-Objekt nicht in ein neues/anderes DLL-Projekt. Fügen Sie das Projekt zu Ihren Referenzen hinzu und importieren Sie die Ausgabe-DLL in Ihre Vorlage? – Thundter

Antwort

7

Dies ist die komplette Lösung:

1) Trennen Sie die Klassen in ein anderes Projekt 2) Fügen Sie den Verweis auf diese Klassen durch den TT über

3) Vergessen Sie nicht zu berücksichtigen e eine Referenz dieser Bibliothek in Ihr TT Projekt

4) Sie haben die MyOwnLibraryProject.dll in dem IST \ debug-Ordner der TT-Lösung erscheint

5) Die Magie kopieren !!!

Jedes Mal, wenn Sie Ihre DLL geändert haben, vergessen Sie nicht, die neue Version in den Ordner zu legen :) Oder konfigurieren Sie einfach Ihre Bibliothek Projektausgabe, um die gleiche wie Ihre TT one. Ich möchte Ihnen allen für die Bereitstellung von Richtlinien und Ideen danken.

+0

Ausgezeichnet. Ich werde dies bei meinen eigenen Projekten berücksichtigen. Ich habe die Klassen – reckface

1

Einschließlich der C# Datei in die T4-Vorlage:

<#@ include file="$(ProjectDir)ClassDefinition.cs" #> 

wird den Text an den Ausgang der T4-Vorlage. Es kompiliert die Klasse nicht.

Sie haben debug = true in Ihrer T4-Vorlage festgelegt, sodass Sie sehen können, was T4 generiert, wenn Sie in Ihrem% TEMP% -Verzeichnis suchen. Wenn Sie Ihre T4-Vorlage ausführen, sollten Sie eine CS-Datei anzeigen, die in dem TEMP-Verzeichnis generiert wird. In dieser Datei werden Sie etwas ähnliches haben:

this.Write("public class ClassDefinition\r\n{\r\n public string NameSpace { get; set; }\r\n p" + 
     "ublic string Name { get; set; }\r\n public string Protection { get; set; }\r\n\r\n " + 
     " List<ClassProperty> Properties { get; set; }\r\n}"); 

Also alles, was zu Ihrer C# Klasse geschieht, ist, dass es in der erzeugten T4 Ausgabe geschrieben wird.

Wahrscheinlich möchten Sie die Datei ClassDefinition.cs in Ihr Projekt einfügen, damit sie als Teil Ihres Projekts kompiliert wird. Dann können Sie auf die Assembly verweisen, die ClassDefinition-Klasse enthält. Also, wenn Ihr Projekt Ausgabe MyLibrary.dll ist, die die ClassDefinition.cs enthält kompilierte dann sollten Sie nutzen können:

<#@ assembly name="$(SolutionDir)$(OutDir)MyLibrary.dll" #> 

Die Linie, die die ClassDefinition.cs Datei enthält sollten entfernt werden.

+0

Ok, diese Lösung wird zu dem, was ich will. TT- und CS-Dateien befinden sich im selben Projekt. Ich möchte, dass der TT die Klassen zum Erstellen von Objekten usw. verwenden kann. Ich überprüfe diesen Weg und werde Sie darüber auf dem Laufenden halten. – Eagle

+0

[link] (http://hpics.li/b6f8a05) Hier ist die Struktur des Projekts. Ich habe die Klassendefinitionsdatei vom Projekt in eine andere getrennt. Ich habe jetzt diesen Fehler. Irgendwelche Ideen ? – Eagle

4

Wenn ich Sie richtig verstehe, versuchen Sie eine Klasse als Teil Ihrer Vorlagengeneration wiederzuverwenden.

Diese Klasse muss in einer tt-Datei selbst sein, Build-Aktion wird auf none gesetzt, benutzerdefiniertes Werkzeug - nichts. Was ich habe, ist eine Template Manager-Klasse mit dem folgenden an der Spitze:

<#@ template language="C#" #> 
<#@ assembly name="System.Core" #> 
<#@ import namespace="System.Linq" #> 
<#@ import namespace="System.Text" #> 
<#@ import namespace="System.Collections.Generic" #> 
<#@ import namespace="System.Diagnostics" #> 

<#+ 
public class TemplateManager 
{ 

dann in den anderen T4-Vorlagen Ich verwende:

<#@ include file="TemplateManager.tt"#> 

und dann

List<Values> values = TemplateManager.PrepareVariables(code, container, itemCollection.OfType<EntityType>()) 

In Ihrem Fall diese Klassendefinition.tt-Datei enthalten würde:

<#@ template language="C#" #> 
<#@ assembly name="System.Core" #> 
<#@ import namespace="System.Linq" #> 
<#@ import namespace="System.Text" #> 
<#@ import namespace="System.Collections.Generic" #> 
<#@ import namespace="System.Diagnostics" #> 

<#+ 
public class ClassDefinition 
{ 
    public string NameSpace { get; set; } 
    public string Name { get; set; } 
    public string Protection { get; set; } 

    List<ClassProperty> Properties { get; set; } 
} 
#> 

Dann können Sie umfassen

<#@ include file="ClassDefinition.tt"#> 
+0

Nein, ich möchte es nicht einfügen, aber es in meiner Vorlage in der Tat zu verwenden – Eagle

0

Addiert man diese nach dem Import-Anweisungen funktionieren sollte:

<# 
ClassDefinition cd = new ClassDefinition(); 
#> 
+0

mit einbezogen, vielleicht musst du mehr erklären, warum das funktionieren sollte ... – Zeina