Armando una aplicación usando AjGenesis (Parte 6)

Published on Author lopezLeave a comment

En el post anterior de esta serie, agregué mucho código para manejar la generación de proyectos y soluciones .NET. Esos archivos son complicados. En contraste, generar algo similar para Java, no estan complejo, porque solo necesitamos generar las estructuras de directorios, y algun archivo para Ant o para Maven. Pero en .NET, tenemos que armar los archivos de proyectos (que no son simples) así como los de las soluciones.

El código de este post pueden bajarlo de AppExampleStep06.zip. Necesitan los binarios de AjGenesisTrunkBinaries.zip. Como siempre el project AjGenesis, incluyendo los ejemplos de esta serie de posts, puede ser bajado desde http://ajgenesis.codeplex.com.

Una de las partes complicadas, en el anterior post, fue agregar los archivos .cs y .vb al archivo del proyecto. Escribí entonces:

for each Entity in Project.Model.Entities
  TransformerManager.Transform("Templates/CSharp/EntityClass.tpl", "${Project.BuildDirectory}/${Project.Name}.Entities/${Entity.Name}.cs", Environment)
  PrjEntities.Includes.Add(CreateFileCs("${Entity.Name}"))
end for

La list Includes dentro del objeto PrjEntities mantiene la información de los archivos a agregar en la generación del archivo de proyecto. En vez de agregar los archivos de esta forma, ahora, en este post, agrego los archivos que están en los directorios. Es decir, podemos ahora tener archivos manuales, escritos por nosotros, dentro del directorio resultado de la generación, y también serán reconocidos dentro de los archivos de proyecto C# y Visual Basic. De esta manera, podemos ir extendiendo los proyectos generados con nuestros propios archivos, que serán conservados en los proyectos despues de la generación de los archivos automáticos. En nuevo código está dentro de  Utilities/DotNetUtilities.ajg:

Sub AddVbFilesToProject(project)
  di = new System.IO.DirectoryInfo(project.Directory)
  prefix = ""
  AddVbFiles(project, name, di)
End Sub
Sub AddVbFiles(project, prefix, di)
  for each fi in di.GetFiles("*.vb")
    name = fi.Name.Substring(0, fi.Name.Length - 3)
    project.Includes.Add(CreateFileVb(prefix & name))
  end for
  
  sdirs = di.GetDirectories()
  
  for each sdir in sdirs
    AddVbFiles(project, prefix & sdir.Name & "\", sdir)
  end for
End Sub
Sub AddCsFilesToProject(project)
  di = new System.IO.DirectoryInfo(project.Directory)
  prefix = ""
  AddCsFiles(project, name, di)
End Sub
Sub AddCsFiles(project, prefix, di)
  for each fi in di.GetFiles("*.cs")
    name = fi.Name.Substring(0, fi.Name.Length - 3)
    project.Includes.Add(CreateFileCs(prefix & name))
  end for
  
  sdirs = di.GetDirectories()
  
  for each sdir in sdirs
    AddCsFiles(project, prefix & sdir.Name & "\", sdir)
  end for
End Sub

Otra “feature” que agregué en este paso: en el anterior post, cada vez que corríamos la generación de código, creaba y pisaba los archivos generados, aunque el contenido fuera al fin igual. Ahora, uso una rutina en Utilities/TransformUtilities.ajg:

Sub TransformFile(tpl, target, tm, env)
  if System.IO.File.Exists(target) then
    target2 = target & ".tmp"
    tm.Transform(tpl, target2, env)
    content1 = System.IO.File.ReadAllText(target)
    content2 = System.IO.File.ReadAllText(target2)
    if content1 <> content2 then
      System.IO.File.Copy(target2, target, true)
    end if
    System.IO.File.Delete(target2)
  else
    tm.Transform(tpl, target, env)
  end if
End Sub

Que sólo pisa el archivo final si es distinto del anterior. Entonces, en vez de invocar directamente al objeto predefinido TransformerManager:

  TransformerManager.Transform("Templates/CSharp/EntityClass.tpl", "${Project.BuildDirectory}/${Project.Name}.Entities/${Entity.Name}.cs", Environment)

las tareas invocak a la nueva rutina, comparando el archivo anterior con el nuevo, para ver si reemplaza o no el archivo destino:

  TransformFile("Templates/CSharp/EntityClass.tpl", "${Project.BuildDirectory}/${Project.Name}.Entities/${Entity.Name}.cs", TransformerManager, Environment)

Próximos pasos, para los siguientes posts: incluir identidad en las entidades del modelo, generar una base de datos desde el modelo, generar código de DAOs, y hasta volver a generar Java, quizás con Ant.

Nos leemos

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

Leave a Reply

Your email address will not be published. Required fields are marked *