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}
${Entity.Name}Dao>
<#
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.
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 Responses to “Generando con AjGenesis desde los assemblies”
RSS feed for comments on this post. TrackBack URL
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
Comment by Angel "Java" Lopez — 21 November 2007 @ 7:53
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.
Ahora tiene más onda.
Con AjGenesis.FromAssembly obtengo solamente la estructura de los objetos y los templates están en AjGenesis
Lo más lindo es que levanto el assembly con AjGenesis… un grande tu bebé !
Saludos
Comment by Dario Quintana — 21 November 2007 @ 13:15
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
Comment by Angel "Java" Lopez — 25 November 2007 @ 5:57
[...] 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 [...]
Pingback by AjGenesis: Modelo desde la Base de Datos - Angel "Java" Lopez — 25 November 2007 @ 12:15
[...] Generando con AjGenesis desde los assemblies [...]
Pingback by AjGenesis: Modelo generado desde los assemblies - Angel "Java" Lopez — 27 November 2007 @ 6:46
[...] with this feature to generate code from compiled code (post in Spanish Generando con AjGenesis desde los assemblies). You can download his utility [...]
Pingback by AjGenesis: Generating the model from the database « Angel “Java” Lopez on Blog — 21 April 2008 @ 6:39
[...] Generando con AjGenesis desde los assemblies [...]
Pingback by AjGenesis: Generating the model from assemblies « Angel “Java” Lopez on Blog — 23 April 2008 @ 7:32