Generating a solution with AjGenesis using NHibernate Hbm files

Some months ago, I wrote an example of code generation, using .hbm files as the initial model:

Generating Code with AjGenesis Using NHibernate Hbm Files

Since then, I improved the example. You can download from the trunk at Codeplex:

I prepared a ready-to-run package, at my Skydrive:

Examples > AjGenesis >

This is its folder structure:

There is two projects: AjFirstExample, and AjTest. The former has only two simple entities. The latter has entities with one-to-many relation. You can generate the code for a complete .NET solution, launching commands:


There are “shortcuts” to

GenerateProject AjFirstExample
GenerateProject AjTest

This is the solution generated for AjTest project:

You can run it as a web site:

In this example, the model, the .hbm files, was enriched with the use of meta tags, like in Employee.hbm in AjTest:

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
  <class name="Employee" table="employees">
    <meta attribute="SetName">Employees</meta>
    <meta attribute="Descriptor">Employee</meta>
    <meta attribute="SetDescriptor">Employees</meta>
    <id name="Id" column="Id" type="Int32">
      <meta attribute="Description">Id</meta>
      <generator class="native"/>
    <property name="EmployeeCode" type="String">
      <meta attribute="Description">Employee Code</meta>
    <property name="LastName" type="String">
      <meta attribute="Description">Last Name</meta>
    <property name="FirstName" type="String">
      <meta attribute="Description">First Name</meta>
    <many-to-one name="Department" column="IdDepartment"
                 class="AjTest.Entities.Department, AjTest.Entities" />
    <bag name="Tasks" lazy="true" inverse="true" cascade="all">
      <key column="IdEmployee"/>
      <one-to-many class="AjTest.Entities.Task, AjTest.Entities"/>
    <bag name="EmployeeSkills" lazy="true" inverse="true" cascade="all">
      <key column="IdEmployee"/>
      <one-to-many class="AjTest.Entities.EmployeeSkill, AjTest.Entities"/>

Note the use of the meta tag at class level, and at property level. AjGenesis run tasks, one is Tasks\LoadMappings.ajg:

include "Utilities/Utilities.tpl"
include "Utilities/FileUtilities.tpl"
include "Utilities/TypeUtilities.tpl"
include "Templates/CSharp/UtilitiesCs.tpl"
include "Templates/CSharp/CSharpFunctions.tpl"
parser = new NHibernate.Cfg.MappingSchema.MappingDocumentParser()
if not Project.BuildDir then
  Project.BuildDir = "Build/${Project.Name}/CSharp"
end if
Project.Entities = CreateList()
for each MappingName in Project.Mappings
  filename = "Projects/${Project.Name}/Mappings/${MappingName}.hbm.xml"
  mapping = parser.Parse(OpenAsStream(filename))
  for each hbmclass in mapping.Items where IsType(hbmclass, "HbmClass")
    Entity = CreateObject()
    Entity.ClassName =
    Entity.Name =
    Entity.Namespace = mapping.namespace
    Message "Processing Mapping of Entity " & Entity.Name
    Entity.Properties = CreateList()
    if hbmclass.Id then
      Property = CreateObject()
      Property.Name =
      Property.Type = HbmTypeToCSharp(hbmclass.Id.type1, Entity.Namespace)
      Property.IsId = True
      for each meta in hbmclass.Id.meta
        Property.SetValue(meta.attribute, meta.GetText())
      end for
    end if
    for each meta in hbmclass.meta
      Entity.SetValue(meta.attribute, meta.GetText())
    end for
    for each item in hbmclass.Items
      Message "Processing Item " & item.GetType().Name
      if IsType(item, "HbmProperty") then
        Property = CreateObject()
        Property.Name =
        Property.SetValue("Description", "Description " &
        Property.Type = HbmTypeToCSharp(item.type1, Entity.Namespace)
        for each meta in item.meta
          Property.SetValue(meta.attribute, meta.GetText())
        end for
      end if
      if IsType(item, "HbmManyToOne") then
        Property = CreateObject()
        Property.Name =
        Property.Type = HbmTypeToCSharp(item.class, Entity.Namespace)
        Property.Reference = HbmTypeToCSharp(item.class, Entity.Namespace)
      end if
      if IsType(item, "HbmSet") then
        Property = CreateObject()
        Property.Name =
        Property.IsSet = true
        Property.Type = HbmTypeToCSharp(item.Item.class, Entity.Namespace)
      end if
      if IsType(item, "HbmBag") then
        Property = CreateObject()
        Property.Name =
        Property.IsList = true
        Property.Type = HbmTypeToCSharp(item.Item.class, Entity.Namespace)
      end if
    end for    
  end for
end for

Note the use of Property.SetValue(…), Entity.SetValue(…) to enrich the in-memory model representation with the new metadata contained in mapping files. As in other AjGenesis examples, the metadata is used to show legends in presentation files, or for whatever you want to put in the tasks and templates.

This is a “proof-of-concept” example. It should be improved to use all the power of NHibernate. But it’s a demostration of the power of an initial model, to create lot of text artifacts, in this case, a ready-to-run application.

More examples are coming, this time using a free model. Keep tuned!

Angel “Java” Lopez

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s