2010-05-02 16 views
6

¿Es posible generar y generar código C# basado en el código del mismo proyecto? Intenté con T4 y Reflection, pero hay algunos problemas de bloqueo de ensamblaje. ¿Hay alguna otra manera?C# Cómo generar código a partir del código

+0

¿Puedo preguntar qué lo desvió del motor de introspección? http://www.olegsych.com/2007/12/how-to-use-t4-to-generate-decorator-classes/ –

+0

Hay algunos problemas con Microsoft.Cci.dll y la licencia FxCop. No está permitido usarlos por separado. Además, estoy bastante familiarizado con el motor T4. – Marko

+1

A partir de VS 2010 SP1, debe haber [sin problemas de bloqueo] (http://blogs.msdn.com/b/garethj/archive/2010/12/11/vs2010-sp1-t4-no-longer-locks-assemblies -in-memory.aspx) cuando se usa la reflexión de T4. – Jon

Respuesta

1

La reflexión funciona bien para mí. Puede evitar problemas de bloqueo de ensamblaje al aislar su tarea de compilación en un Dominio de aplicación separado dentro de VS. Cuando la tarea finalice, todos los ensamblajes que necesite utilizar para la generación de código se descargarán junto con el dominio de aplicación de la tarea. Ver AppDomainIsolatedTask.

+0

No estoy seguro de si entiendo. Debería escribir mi propia tarea de compilación, que hereda AppDomaniIsolatedTask e inicia el generador de código T4. ¿Es asi? – Marko

+0

Sí, de esta manera usted debería ser capaz de evitar VS bloqueando sus ensamblajes durante las compilaciones. En cuanto al generador de código real, usa lo que más te convenga: T4 si te gusta T4. –

0

Realmente depende de lo que exactamente está tratando de lograr, pero en un caso general lo recomiendo el uso de plantillas T4.

Y sí, es posible usar plantillas T4 dentro de su proyecto para generar código en su proyecto basado en algunas configuraciones locales, pero debe definir lo que está tratando de hacer.

Si desea generar código basado en algunas clases que defina en el mismo proyecto, esto no parece algo fácilmente alcanzable (después de todo lo que desea compilar algunas de las clases en el proyecto actual, genere algún código basado en ellos y después de eso generar clases de nuevo ... umm ...?)

Pero si desea almacenar algunas configuraciones y luego ejecutar la plantilla T4 y generar algún código basado en estas configuraciones, esto es fácil de lograr. T4MVC es un ejemplo (generan código basado en un archivo de configuración que se copia y almacena en el proyecto junto con la plantilla T4). Esta plantilla también examina los archivos actuales disponibles en la solución y genera constantes de cadena basadas en cada archivo. Eso suena como que realmente te ayudaría con tu problema, sea lo que sea :)

Si aún no estás seguro, puedes especificar más detalles sobre lo que quieres hacer, y trataremos de ayudarte :)

+0

Gracias por la respuesta. Lo que estoy tratando de lograr es poder generar código adicional basado en las clases de mi proyecto. Algo así como CloneEntity(), SerializeEntity() o InvokeSomeMethod. Todo este código depende de los nombres de las clases, los miembros ... El código generado puede estar en otro proyecto, pero sería más agradable mantener todo junto. – Marko

+0

Ya veo ... Lo más probable es que tengas que mantener estas clases en un proyecto separado, ya que estás tratando de generar código en entidades semi-generadas, y no estoy seguro si eso es posible. Suena como si siguieras exactamente el mismo enfoque que estabas usando, pero mantén estos T4 en un ensamble por separado, debería funcionar (no tiene que ser un ensamblaje separado con SÓLO los T4 por supuesto ... Puedes tener cualquier otro tipos de cosas allí, pero el T4 debería reflejar las clases en un ensamble separado, ya compilado :)) ¡Buena suerte! –

1

Definitivamente puedes escribir tu propio generador de código, todo en C# - después de todo, el "código" que se está generando es solo un archivo de texto que escribes.

¿Pero qué pasa con las plantillas T4? Ofrecen muchas funcionalidades que no tiene que reinventar una vez más, ¿por qué no usarlas? ¿Puede decirnos con más detalle qué problemas tiene con T4?

T4 es realmente solo un montón de clases en .NET, así que definitivamente podría escribir su propio generador de código manejando parte de la lógica y usar T4 para hacer la plantilla & reemplazando esa parte de valores de plantilla. Pero de nuevo: para ayudarlo a diagnosticar sus problemas de T4, necesitaríamos saber más sobre ellos ...

+0

Por ejemplo, me gustaría generar un CloneEntity para mi modelo L2S. Necesito leer las propiedades y generar el método Clonar. Se puede hacer con T4 y reflexión, pero existe ese problema sobre el bloqueo de ensamblaje. Debe cerrar VS y abrirlo de nuevo después de cada ejecución. – Marko

+1

En cuanto a CloneEntity: ¿por qué no simplemente serializar la entidad a una secuencia de memoria y deserializarla desde allí? Es la forma estándar de hacerlo, está demostrado que vale la pena, no requiere engaño ni generación de código ... –

1

This example from Oleg Sych usa el motor de introspección de FXCop en lugar de la reflexión. De esa forma, las asambleas no se bloquean.

Desafortunadamente, Reflection está optimizado para la ejecución del código. Una limitación particular de lo hace inadecuado para la generación de código - un conjunto cargado usando Reflection solo se puede descargar con su AppDomain. Debido a que las plantillas T4 están compiladas.NET ensamblados y almacenados en caché para mejorar rendimiento de generación de código, usando La reflexión para acceder al componente hace que T4 lo bloquee.

Alternativamente, si solo está segmentando las clases de SQL a Linq, podría generar código a partir del archivo dbml en lugar del código que genera L2S desde el dbml. I've got an example of something similar (an edmx file) on my own blog.

Cuestiones relacionadas