En este segundo post de la serie explicando cómo armar una aplicación usando AjGenesis, mi proyecto open source de generación de código. El anterior post de la serie:
Building An Application Using AjGenesis (Part 1)
Armando una aplicación usando AjGenesis (Parte 1)
En esta segunda parte, generaré dos archivos sencillos, a partir del modelo definido en el anterior post.
Los archivos para este segundo paso pueden ser bajados desde AppExampleStep02.zip.
Necesitaran bajarse los binarios de AjGenesis (la versión del trunk) desde AjGenesisTrunkBinaries.zip, expandirlos, Y agregar el directorio bin a su path.
Hay un comando PrintEntities.cmd:
AjGenesis.Console Project.xml PrintEntities.ajg
El programa AjGenesis.Console (parte de los binarios de AjGenesis) es un programa de consola que lanza el proceso del generador. Puede recibir varios argumentos. Si el argumento es un archivo .xml su contenido se toma como modelo en memoria (más abajo veremos cómo se usa entonces=. Si el argumento es un archivo .ajg, su contenido se toma como una tarea a ejecutar, escrita en un lenguaje interpretado, llamado afectuosamente AjBasic..
Este es el contenido de Project.xml (lo había definido en el anterior post, más detalles ahí):
<Project> <Name>AjApp</Name> <Description>Building an Application using AjGenesis</Description> <Model> <Entities> <Entity Source="Customer.xml"/> <Entity Source="Supplier.xml"/> </Entities> </Model> </Project>Una vez que el modelo de este archivo es cargado en memoria, tenemos a nuestra disposición una variable pública Project, con propiedades dinámicas, una por cada atributo o elemento inmediato. Desde AjBasic podemos acceder, entonces, a Project, Project.Model, Project.Name, Project.Model.Entities…
El contenido de PrintEntities.ajg:
for each Entity in Project.Model.Entities Message "Entity " & Entity.Name for each Property in Entity.Properties Message " Property ${Property.Name}" end for end forNoten el uso de for each, que es un comando AjBasic. Message es otro comando, que imprime un mensaje en el standard output. El código de arriba también muestra una de las características de AjBasic: la “expansión de String” (inspirada en PHP y otros). Esto es, el string:
“ Property ${Property.Name}”
se expande en ejecución al contenido de la expresión entre ${ y }. Si ejecutamos
PrintEntities.cmd
la salida es:
Entity Customer
Property NameProperty Address
Entity Supplier
Property Name
Property Address
Ahora, generamos un archivo con el texto de una clase en C#, por cada una de las entidades en el modelo. Usamos el comando GenerateClasses.cmd que consiste de:
AjGenesis.Console Project.xml GenerateClasses.ajg
Este comando carga en memoria el contenido de Project.xml como modelo listo para ser accedido desde la variable Project en AjBasic, y ejecuta la tarea:
for each Entity in Project.Model.Entities TransformerManager.Transform("EntityClass.tpl", "${Entity.Name}.cs", Environment) end forHay algunos pocos objetos ayudantes, predefinidos en el ambiente que AjGenesis le provee al intérprete de AjBasic. Uno de los más usados es el TransformerManager, cuyo método Transform toma tres argumentos (ver el código fuente del proyecto AjGenesis para más detalle de TransformerManager y otros objetos auxiliares):
– El nombre del archivo template
– El nombre del archivo a generar– El Environment actual (nombre/valor de las variables globales y funciones, usualmente apuntados por la variable global Environment)
Este es el primer template en esta serie de tutoriales, EntityClass.tpl:
// Entity Class, generated with AjGenesis (http://ajgenesis.codeplex.com) public class ${Entity.Name} { <# for each Property in Entity.Properties #> public string ${Property.Name} { get; set; } <# end for #> }Un template (plantilla) es un archivo de texto con el contenido a generar, y con fragmentos de AjBasic, contenidos entre <# y #>. En el ejemplo de arriba, el comando for each recorre cada una de las propiedades de la entidad bajo proceso. En el texto mismo de un template también hay expansión de string, así que las expresiones entre ${ y } son evaluadas en el momento y su resultado se inserta en lugar de la expresión.
Queda entonces esta salida generado, ejemplo Customer.cs usando el EntityClass.tpl de arriba:
// Entity Class, generated with AjGenesis (http://ajgenesis.codeplex.com) public class Customer { public string Name { get; set; } public string Address { get; set; } }He dejado algunas simplificaciones: no hay namespace, no hay id para las entidades, todas las propiedades se supone strings, etc… Extenderé el ejemplo en próxumos pasos para resolver esos temas. También hay que encarar: generar, desde el mismo modelo, clases VB.NET, C# o Java, a pedido. Y en algún momento, generar un proyecto completo. Más adelante, agregar capa de presentación, de persistencia, creación de la base, etc, en distintas tecnologías. Pero vayamos paso a paso
(Ya comenté que el otro camino es AjGenetizando una aplicación: partir de una aplícación ya armada, y comenzar a abstraer desde ahí, y hasta iterar: generar manual, abstraer, poner en generación automática, mantener lo manual, etc…. Pero creo que esta serie de tutorial es más fácil de entender, para el que reciíen llega a este proyecto).
Nos leemos!
Angel “Java” Lopez ie
http://www.ajlopez.com