2010-05-02 12 views
6

È possibile generare e creare un codice C# basato sul codice dello stesso progetto. Ho provato con T4 e Reflection, ma ci sono alcuni problemi di blocco degli assiemi. C'è un altro modo?C# Come generare codice dal codice

+0

Posso chiederti cosa ti ha staccato dal motore di introspezione? http://www.olegsych.com/2007/12/how-to-use-t4-to-generate-decorator-classes/ –

+0

Ci sono alcuni problemi con la licenza Microsoft.Cci.dll e FxCop. Non è consentito utilizzarli separatamente. Inoltre, sono abbastanza familiare con il motore T4. – Marko

+1

A partire da VS 2010 SP1 dovrebbe esserci [nessun problema di blocco] (http://blogs.msdn.com/b/garethj/archive/2010/12/11/vs2010-sp1-t4-no-longer-locks-assemblies -in-memory.aspx) quando si utilizza il riflesso da T4. – Jon

risposta

1

Reflection funziona bene per me. È possibile risolvere i problemi di blocco dell'assieme isolando l'attività di compilazione in un AppDomain separato in VS. Una volta completata l'attività, tutti gli assembly che è necessario utilizzare per la generazione del codice verranno scaricati insieme all'AppDomain dell'attività. Vedi AppDomainIsolatedTask.

+0

Non so se capisco. Dovrei scrivere la mia attività di compilazione che eredita AppDomaniIsolatedTask e avvia il generatore di codice T4. È così? – Marko

+0

Sì, in questo modo dovresti essere in grado di aggirare VS bloccando i tuoi assembly durante i build. Per quanto riguarda il generatore di codice attuale, usa ciò che ti si addice meglio: T4 se ti piace il T4. –

0

Dipende molto da che cosa esattamente stai cercando di raggiungere, ma in un caso generale mi consiglia di utilizzare modelli T4.

E sì, è possibile utilizzare i modelli T4 all'interno del progetto per generare codice nel progetto in base ad alcune impostazioni locali, ma è necessario definire cosa si sta tentando di fare.

Se si desidera generare codice in base ad alcune classi definite nello stesso progetto, questo non suona come qualcosa facilmente realizzabile (dopo tutto si desidera compilare alcune delle classi nel progetto corrente, generare del codice basato su di essi e dopo di che generare di nuovo classi ... umm ..?)

Ma se si desidera memorizzare alcune impostazioni e quindi eseguire il modello T4 e generare un codice basato su queste impostazioni, questo è facilmente realizzabile. T4MVC è un esempio (generano codice basato su un file di impostazioni che viene copiato e archiviato nel progetto insieme al modello T4). Questo modello analizza anche i file correnti disponibili nella soluzione e genera costanti di stringa in base a ciascun file. Questo tipo di suoni ti aiuterà davvero con il tuo problema, qualunque cosa sia :)

Se non sei ancora sicuro, puoi specificare più dettagli su ciò che vuoi fare e cercheremo di aiutarti :)

+0

Grazie per la risposta. Quello che sto cercando di ottenere è di essere in grado di generare codice aggiuntivo basato su classi nel mio progetto. Qualcosa come CloneEntity(), SerializeEntity() o InvokeSomeMethod. Tutto questo codice dipende dai nomi delle classi, membri ... Il codice generato può essere in un altro progetto, ma sarebbe meglio tenere tutto insieme. – Marko

+0

Vedo .. Probabilmente dovresti tenere queste classi in un progetto separato, mentre stai provando a generare codice su entità semi-generate, e non sono sicuro che sia possibile. Sembra che se segui esattamente lo stesso approccio che stavi usando, ma tieni questi T4 in un assembly separato - dovrebbe funzionare (non deve essere un assembly separato con JUST the T4s ovviamente .. Puoi avere qualsiasi altro tipi di cose lì dentro, ma il T4 dovrebbe riflettere le classi in un assembly separato, già compilato :)) Buona fortuna! –

1

Si può sicuramente scrivere il proprio generatore di codice, tutto in C# - dopo tutto, il "codice" che viene generato è solo un file di testo che scrivi.

Ma cosa c'è di sbagliato con i modelli T4? Offrono molte funzionalità che non è necessario reinventare di nuovo, perché non utilizzarle? Puoi dirci in modo più dettagliato quali problemi hai con T4?

T4 è davvero solo un insieme di classi in .NET, quindi è possibile scrivere il proprio generatore di codice gestendo parte della logica e utilizzare T4 per eseguire il modello & sostituendo la parte relativa ai valori del modello. Ma ancora: per aiutarvi a diagnosticare i vostri problemi T4, avremmo bisogno di saperne di più su questi ....

+0

Ad esempio, vorrei generare un CloneEntity per il mio modello L2S. Ho bisogno di leggere le proprietà e generare il metodo Clona. Può essere fatto con T4 e reflection, ma c'è quel problema sul locking assembly. Devi chiudere VS e aprirlo di nuovo dopo ogni corsa. – Marko

+1

Per quanto riguarda CloneEntity: perché non serializzare semplicemente l'entità in un flusso di memoria e deserializzare da lì? È il modo standard di farlo, ne è valsa la pena, non richiede alcun trucco o codice di generazione ... –

1

This example from Oleg Sych utilizza il motore di introspezione di FXCop anziché la riflessione. In questo modo, gli assiemi non vengono bloccati.

Sfortunatamente, Reflection è ottimizzato per l'esecuzione del codice. Una particolare limitazione lo rende poco adatto alla generazione del codice - un assembly caricato utilizzando Reflection può essere scaricato solo con il suo AppDomain. Perché i modelli T4 sono compilati in.Gli assembly NET e memorizzati nella cache per migliorare le prestazioni di generazione codice , utilizzando Reflection per accedere all'assieme componente causa il blocco di T4.

In alternativa, se si stanno indirizzando solo le classi da Linq a SQL, è possibile generare codice dal file dbml anziché dal codice generato da L2S dal dbml. I've got an example of something similar (an edmx file) on my own blog.

Problemi correlati