2014-07-25 16 views
6

Vorrei utilizzare la mia classe definita in un file CS nel mio TT.T4 - TT - Uso di classi personalizzate in file TT

Esempio:

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

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

mio TT si presenta come:

<#@ 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(); 

Ma ho questo messaggio di errore:

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

ho controllato su internet e ha cercato di: - uso includi - usa l'assemblaggio - usa USING Ma niente funziona.

Qualche idea?

+0

Questo può sembrare una domanda ovvia, ma è il vostro file ClassDefinition.cs nello stesso progetto del file .tt *? – Thundter

+0

Sì, è nello stesso progetto! – Eagle

+0

Perché non spostare l'oggetto ClassDefinition in un nuovo/diverso progetto dll. Aggiungi il progetto ai tuoi riferimenti e importa la dll di output nel tuo modello? – Thundter

risposta

7

Ecco la soluzione completa:

1) Separare le classi in un altro progetto 2) Includere il riferimento a queste classi attraverso il TT via

<#@ assembly name="$(TargetDir)MyOwnLibraryProject.dll" #> 
<#@ import namespace="MyOwnNamespace" #> 

3) Non dimenticare di includere e un punto di riferimento di questa libreria nel progetto TT

4) È necessario copiare il MyOwnLibraryProject.dll nella cartella bin \ debug della soluzione TT

5) La magia appaiono !!!

Ogni volta che si modifica la DLL, non dimenticare di inserire la nuova versione nella cartella :) Oppure basta configurare l'output del progetto Libreria per essere uguale a quello TT. Vorrei ringraziare tutti voi per aver dato linee guida e idee.

+0

Eccellente. Terrò questo a mente per i miei progetti. Ho incluso le classi – reckface

1

Compreso il file C# nel modello T4 utilizzando:

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

aggiungerà il testo per l'uscita del modello T4. Non compila la classe.

Hai debug = true impostato nel modello T4 in modo da poter vedere cosa sta generando T4 se si guarda nella directory% TEMP%. Quando esegui il tuo modello T4 dovresti vedere un file .cs generato nella directory TEMP. In questo file può avere qualcosa di simile a:

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}"); 

Quindi, tutto ciò che sta accadendo al vostro classe C# è che sarà scritto nel T4 uscita generato.

Quello che probabilmente si vorrebbe fare è includere il file ClassDefinition.cs nel progetto in modo che sia compilato come parte del progetto. Quindi è possibile fare riferimento all'assembly che include la classe ClassDefinition. Così, se il progetto è uscita MyLibrary.dll, che contiene le ClassDefinition.cs compilato allora si dovrebbe essere in grado di utilizzare:

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

La linea che include il file ClassDefinition.cs dovrebbe essere rimosso.

+0

Ok questa soluzione sta andando a quello che voglio. I file TT e cs si trovano nello stesso progetto. Voglio che il TT sia in grado di usare le Classi per creare oggetti, ecc. Verificherò in questo modo e ti terrò informato su questo. – Eagle

+0

[link] (http://hpics.li/b6f8a05) Ecco la struttura del progetto. Ho separato il file classdefinition dal progetto in un altro. Ho ora quell'errore. Qualche idea ? – Eagle

4

Se ho capito bene, stai cercando di riutilizzare una classe come parte della generazione del tuo modello.

Quella classe deve essere in un file tt, l'azione di creazione non è impostata su nessuno, lo strumento personalizzato - nulla. Quello che ho è una classe template manager con il seguente in alto:

<#@ 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 
{ 

Poi negli altri modelli T4 che uso:

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

e poi

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

Nel tuo caso che ClassDefinition.file di TT dovrebbe contenere:

<#@ 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; } 
} 
#> 

Quindi è possibile includere

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

No Non voglio includerlo ma usarlo nel mio template infatti – Eagle

0

L'aggiunta di questo, dopo le sue dichiarazioni di importazione dovrebbe funzionare:

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

forse hai bisogno di spiegare di più perché questo dovrebbe funzionare ... – Zeina