Generando con AjGenesis desde los assemblies

AjGenesis es una herramienta de generación de código a partir de templates y un modelo libre.

Bien vayamos a esta frase, se dice rápido… pero analicemosla: "…a partir de templates…", esto no tiene nada de nuevo, MyGeneration lo hace, y millones de generadores de código que andan sueltos por ahí también. Pero el punto más que interesante está: "a partir de un modelo libre", y esto que quiere decir ? Significa que no hay restricciones sobre como debe ser el modelo. Si bien debe ser escrito en Xml, esta es una forma de representar el modelo para que lo analice AjGenesis, esto no puede ser considerado una restricción.

Ahora bien, el modelo de AjGenesis puede ser generado inclusive desde la base de Datos, existen unos ejemplos de ello disponible junto con la distribución de AjGenesis.

Hace un tiempo salió la inquietud de que AjG podría generar el modelo a partir de los hbm de NHibernate, la gente que usa NHibernate estaría contenta incluyendome. Pero estuve pensando que los xml se deberían sobrecargar con muchos datos que por ahora los defaults de NHibernate los consideran dejando el mapping más limpio y fácil de leer. Por ejemplo, mis mappings files no tienen el tipo de dato (salvo excepciones), NHibernate hace el trabajo, sin esta información, el modelo que se genere ó el código que se genere junto a los templates es casi inutil sin los tipos de datos.

Otra opción para generar el modelo, es a partir de las clases disponibles en los ensamblados de la aplicación que estemos usando. Hace un tiempo escribí esta herramienta que ahora decidí cambiarla un poco. Ahora escribí ésta herramienta que la pueden descargar aquí.

Como funciona AjGenesis.FromAssembly? Facil,  es una librería que itera sobre un ensamblado especificado y devuelve una lista de Objetos que representan la estructura de las clases:

<#
AjGenesisFromAssemblyPath = "..\..\bin\AjGenesis.FromAssembly.dll"
function GetEntities(path)

	AssemblyManager.LoadFrom(AjGenesisFromAssemblyPath)
	obj = new AjGenesis.FromAssembly.Collector()
	list = obj.GetEntities(path,null)
	return list

end function

AssemblyManager es la clase encargada de cargar el assembly, una vez hecho esto podemos trabajar con él.

Para obtener la listar las clases en el assembly usamos la clase Collector, y la función GetEntities, especificando la ruta del ensamblado.

El template para generar la configuración de IoC en el xml, podría ser similar a este:

<#
nsServices = "MyApp.Service"
assemblyName = "MyApp.Service"
moneySign = "$"
oBraces = "{"
cBraces = "}"
include	"${TemplateDir}\Functions.tpl"
#>


  
<#
	for each Entity in Entities
#>


		<${Entity.Name}Dao>${moneySign}${oBraces}${Entity.Name}.Dao${cBraces}
		
	
    
<#
	end for
#>
	

Algo interesante al generar código que a su vez tiene instrucciones de un lenguaje “tipo” template, es decir con comandos de esta forma ${variable}, es que debemos usar caracteres en el código generado y en el codigo para que lo interprete el generador de código. AjGenesis en los templates y Windsor en la configuración, usan los caracteres $, {, }. De modo que para no que AjGenesis no se confunda en el parseo, creé variables que contienen estos símbolos.


Descargar Aquí

Existen muchas cosas que se me ocurrieron para mejorarlo, pero la base ya está, ahora hay que empezar a retocarla. Se me planteó la inquietud crear atributos (annotations) para las clases de modo que se pueda enriquecer o restringir el modelo generado. Pero supongo que sería la primera herramienta de generación de código intrusiva que se pueda configurar por medio de annotaciones y quizas se convertiría en overhead para la aplicación.

7 comments so far

  1. Angel "Java" Lopez Noviembre 21, 2007 7:53

    Hola Dario!

    Gracias por publicar este articulo, y colocar tu codigo ahora en Google. Lo habia visto en tu anterior blog. Bien, en cuanto pueda blogueo sobre el tema.

    Nos leemos!

    Angel “Java” Lopez

  2. Dario Quintana Noviembre 21, 2007 13:15

    Hola Angel,

    Pero este es distinto del anterior, por que en el anterior yo generaba el modelo por “fuerza bruta” en c# y era un programa que no necesitaba de AjGenesis.
    Con AjGenesis.FromAssembly obtengo solamente la estructura de los objetos y los templates están en AjGenesis ;) Ahora tiene más onda.
    Lo más lindo es que levanto el assembly con AjGenesis… un grande tu bebé !

    Saludos

  3. Angel "Java" Lopez Noviembre 25, 2007 5:57

    Ah! Barbaro!

    Sos el primer usuario del AssemblyManager!!

    Bien, te cuento que tambien ahora podes usar metodos estaticos como System.IO.File.Move(….). Asi que tendria que probar System.Reflection.Assembly.LoadFrom(…).

    Ese uso de metodos estaticos es uno de los agregados de la version 0.5. No hay import. Hay que poner el nombre completo, al igual que con los new.

    La idea del AssemblyManager es cargar DLLs de una forma controlada, haciendo probing a la AjGenesis si es necesario (relativo al path del template y esas cosas, pero no esta implementado).

    Bien lo de atributos! Hmm… se me ocurre EJB3 como ejemplo.

    Nos leemos!

    Angel “Java” Lopez

  4. [...] postear sobre el uso que le dió el bueno de Darío Quintana a esta "feature", ver Generando con AjGenesis desde los assemblies). Me imagino que podemos usar, por ejemplo, la librería Meta de MyGenerationSoftware para [...]

  5. [...] Generando con AjGenesis desde los assemblies [...]

  6. [...] with this feature to generate code from compiled code (post in Spanish Generando con AjGenesis desde los assemblies). You can download his utility [...]

  7. [...] Generando con AjGenesis desde los assemblies [...]

Leave a comment

Please be polite and on topic. Your e-mail will never be published.