2013-01-15 11 views
9

Sto riscontrando un problema nella creazione di un modo per elencare tutte le classi nel mio progetto utilizzando EnvDTE per le interfacce di modelli utilizzando T4 (in base alle convenzioni di denominazione) e nessuna documentazione fuori sembra che descriva come farlo. Ho iniziato con:Raccogliere un elenco di classi utente in un progetto utilizzando EnvDTE

<#@ template debug="true" hostspecific="true" language="C#" #> 
<#@ output extension=".cs" #> 
<#@ Assembly name="EnvDTE" #> 
<#@ Assembly name="System.Core" #> 
<#@ import namespace="EnvDTE" #> 
<#@ Import Namespace="System.Linq" #> 
<#@ Import Namespace="System.Collections.Generic" #> 
<# 
    var env = (DTE)((IServiceProvider)this.Host) 
     .GetService(typeof(EnvDTE.DTE)); 

... e poi ho iniziato ad andare di lato. Sono in grado di identificare il mio progetto, ma non sono in grado di raccogliere le classi nel progetto che voglio filtrare in un elenco semplice per la creazione di interfacce.

Come posso fare questo? Voglio solo le lezioni nel mio progetto.

+0

Presumo che si tratti di Visual Studio. Se è così, hai guardato Roslyn? – Ameen

+2

Guarda la mia risposta qui http://stackoverflow.com/a/6572941/157224 su come trovare le classi con DTE – adrianm

+0

@adrianm, sembra che potrebbe essere quello che sto cercando (una volta che ho tradotto in C#) ... Ci proverò questo al mattino. –

risposta

10

Dal momento che si sta utilizzando T4 Vorrei suggerire di controllare il tangible T4 Editor. Nella loro galleria è un template riutilizzabile gratuito "tangibile Visual Studio Automation Helper". Con questo modello puoi facilmente trovare Classi di codice ecc. (Vedi la mia risposta a questo post Design Time Reflection).

Se si vuole fare da soli si dovrebbe continuare in questo modo:

var project = env.ActiveDocument.ProjectItem.ContainingProject; 
foreach(EnvDTE.CodeElement element in project.CodeModel.CodeElements) 
{ 
    if (element.Kind == EnvDTE.vsCMElement.vsCMElementClass) 
    { 
     var myClass = (EnvDTE.CodeClass)element; 
     // do stuff with that class here 
    } 
} 

ho rimosso la ricorsione che sarebbe necessario. Un CodeElement può contenere altri CodeElements. Ma in questo modo è più facile da leggere.

0

Non so a molto sui modelli T4, ma si può utilizzare Reflection in uno per ottenere il vostro classe

Esempio:

<#@ template debug="true" hostspecific="true" language="C#" #> 
<#@ output extension=".cs" #> 
<#@ Assembly name="EnvDTE" #> 
<#@ Assembly name="System.Core" #> 
<#@ import namespace="EnvDTE" #> 
<#@ Import Namespace="System.Linq" #> 
<#@ Import Namespace="System.Collections.Generic" #> 
<#@ Import Namespace="System.Reflection" #> 
<# 

    var list = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsClass); 
+0

Riflessione, sfortunatamente, si rimbalza quando si cerca di riflettere su se stessi. Memorizza i dati nella cache e non si aggiorna necessariamente quando si modifica il codice. –

+0

È solo in un modello T4, perché non ho mai visto quel problema prima di –

+0

Sì, praticamente. –

Problemi correlati