Angel “Java” Lopez on Blog

July 21, 2009

Code generation and the Developer Job

Filed under: AjGenesis, Code Generation — ajlopez @ 3:15 pm

Yesterday, July 20th, @hallo twittered:

He received many response, this was mine, and another  one:

We were doing code generation every day for decades. The tool is named: compiler. Do you remember the old days? Setting relays in the ENIAC? Or using the front panel to setup the first Altair microcomputer? The compiler generates code from a higher lever model: programming language.

But for the last three decades, we didn’t raise the level of abstraction. Exceptions: SQL language, or Visual Basic form designer (a graphic model that relieved us of pages and pages of Petzoldoid Windows code).

Code generation from a model (as I promote from my personal project AjGenesis), is the way to get a new “language”: a domain specific language, or a domain specific model, or whatever you want to create.

Today we have so many technologies, with bunch of details and configurations. I think on combining Spring Framework, Hibernate, Struts 2, JavaServer Faces, ASP.NET MVC, Web Services, Windows Communication Foundation, etc… We are wiser on software developer, but current apps are polluted of tons of details and technicalities. Most of these details could be derived from a model.

It’s the same that saying: “a=fact(4)” is the model, and machine registers, stack manipulation, memory allocation, and so, are the details.

More answers:

Yes, manipulating processor registers could be cool the first time, but after hours and hours, it becomes boring (and troublesome). That was the motivation for assemblers, macro assembles, high level languages and compilers.

In my above tweet, I mentioned artificial intelligence. Well, I must admit it’s only an idea, but I think code generation is an appropiate field to apply "artificial intelligence” approaches (yes, AI is broad term these days).

Another question:

Well, it’s hard in the short and medium term. First: there are lot of technologies, and every year we have a new kid of the block (Scala, Clojure, Rest, Cloud Computing, Sharding database, Mobile apps… etc). So, there is no single way of doing software. But in each of such niche, there are a lot of place to nurture abstraction, and to hide boring details.

I agree. But we could dream: applications creating applications… Could we have this kind of apps? In Star Trek future? :-)

Code generation: sky is the limit (AjGenesis motto… :-)

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

June 21, 2009

Code Generation for Mere Mortals Framework

In the current project, my agile team is developing a full health application (Medusa Project), using Mere Mortals Framework as a base to business objects, persistence and WinForm/ASP.NET presentation. You can download a trial version of this framework:

http://www.oakleafsd.com/

There is a feature list at

http://www.oakleafsd.com/MMNetFeatures/pgMMNetFeatures.htm

You can download the developer Guide from

MM .NET Developer’s Guide

The framework were developed by Kevin McNeish, Microsoft MVP, president and Chief Architect of Oak Leaf Enterprise. The framework supports typed entities, but in the background, it’s based on datasets. You can generate a business objects project from templates, and with a code generator provided by the product, you can populate that library with classes, derived from a database.

In my team, we are feeding metadata reading database information, and then, we are generating a full ASP.NET Web Application, a business object libraries, stored procedures, and DDLs for database regeneration. All using AjGenesis, my open source code generation utility. I should post about the experience. The seed task and templates, were derived from the example:

AjGenesis- Generating the model from the database

In this post, I describe another approach: starting from an abstract model, I’m generating:

- Scripts for creating the database
- Business Objects a la Mere Mortals class library
- WinForm project with maintenance forms

I posted about generating applications from an abstract model at:

Application Generation using AjGenesis

but caveat: AjGenesis is based in a free model. You can model what you want. The trivial example:

Code Generation with AjGenesis- A Hello World application

The model

You can download the example from the Codeplex project site example page:

MereMortalsExamples200906.zip

It contains:

The model resides in Projects/AjFirstExample/Project.xml

<Project>

    <Name>AjFirstExample</Name>

    <Description>First Example using AjGenesis</Description>

    <Prefix>AjFE</Prefix>

    <Domain>com.ajlopez</Domain>

    <CompanyName>ajlopez</CompanyName>

    <Model>

        <Entities>

            <Entity Source="Entities/Customer.xml"/>

            <Entity Source="Entities/Supplier.xml"/>

        </Entities>

        <Lists>

            <List Entity="Customer"/>

            <List Entity="Supplier"/>

        </Lists>

        <Forms>

            <Form Entity="Customer"/>

            <Form Entity="Supplier"/>

        </Forms>

        <Views>

            <View Entity="Customer"/>

            <View Entity="Supplier"/>

        </Views>

    </Model>

</Project>

There are two entities, Customer and Supplier. The Customer entity:

<Entity>

    <Name>Customer</Name>

    <Description>Customer Entity</Description>

    <SetName>Customers</SetName>

    <Descriptor>Customer</Descriptor>

    <SetDescriptor>Customers</SetDescriptor>

    <SqlTable>Customers</SqlTable>


    <Properties>

 

        <Property>

            <Name>Id</Name>

            <Type>Id</Type>

        </Property>

 

        <Property>

            <Name>Name</Name>

            <Type>Text</Type>

            <SqlType>varchar(200)</SqlType>

        </Property>

 

        <Property>

            <Name>Address</Name>

            <Type>Text</Type>

            <SqlType>text</SqlType>

        </Property>

 

        <Property>

            <Name>Notes</Name>

            <Type>Text</Type>

            <SqlType>text</SqlType>

        </Property>

 

    </Properties>

</Entity>

 

There is a technology dependent model at Projects/AjFirstExample/Technologies/VbNet3.xml:

<Technology>

    <Programming>

        <Dialect>VbNet3</Dialect>

    </Programming>

    <Database>

        <Dialect>MsSql</Dialect>

        <Name>AjFirstExampleMM</Name>

        <Host>(local)</Host>

    </Database>

</Technology>

You can change the host to .\SQLEXPRESS if you don’t have a running MS SQL Server. You can add <Username> and <Password> if you are using SQL security. If there are not present, the code uses integrated security.

Generating the application

You must download AjGenesis current release 0.5 from http://ajlgenesis.codeplex.com. Add the bin directory to your path. Then, run from the example directory:

GenerateProject.cmd AjFirstExample VbNet3

The first parameter is the project name, and the second is the technology to use. The command invokes

AjGenesis.Console Projects\%Project%\Project.xml tasks\BuildProject.ajg  Projects\%Project%\Technologies\%Technology%.xml tasks\BuildTechnology.ajg tasks\BuildProg.ajg tasks\BuildSql.ajg

It loads the project model, execute the BuildProject task, then loads the technology model, executes the BuildTechnology tasks. The task BuildProg generates the code, and BuildSql generates the DDL to create the database.

It creates a new folder, Build, containing

In Sql folder, you find the ExecuteAll.cmd to create the database

You can run it with a parameter, specifiying your server:

ExecuteAll.cmd Bombadil

If you run this command without a parameter, it uses the host specified in the technology model. There is a VS 2008 solution with two projects, in Src folder:

You can load and compile in Visual Studio (you must have Mere Mortals Fwk installed).

The class library project contains Mere Mortal business objects definition (using partial classes, data access calling stored procedures, rules)

The Win form project has two maintenance forms, for Customers and Suppliers:

Well, it’s not the “killer application” but it’s running:

You can download the generated solution, from my Skydrive

AjFirstExampleMereMortals.zip

Conclusions

Using an abstract model, we can generate the usual text artifacts required by Mere Mortals fwk (or any other framework, technology). With partial classes and separated files, we can regenerate the code from the model, without losing our manual code. We can augment the generated code with automatic validation, rules, and any coding standard we were using.

But the main point, for me, it’s that using an abstract model, we are separating the important core from the technicalities. I could regenerate the application with other base framework, other languages, but our model could be the same. The model describes what we want. Tasks and templates compose an expert system, that knows HOW to get what we want as application.

Angel “Java” Lopez

http://www.ajlopez.com/en

http://twitter.com/ajlopez

May 28, 2009

AjGenesisCF: code generation for .NET Compact Framework

Filed under: .NET, AjGenesis, Code Generation — ajlopez @ 10:29 am

Thanks to Federico Boerr and his team, there is a new version of AjGenesis, rewritten to run using .NET Compact Framework:

http://ajgenesiscf.codeplex.com/

This version uses only the reflection features supported by CF. Then, you don’t have all the original features. As example, the creation of instances using parameters in the constructor is not supported in CF. But you can compile AjGenesis as a .DLL, and invoke it from your program, use templates, tasks and AjBasic. The published code contains a sample program.

More information about the original program at:

http://ajgenesis.codeplex.com
http://ajlopez.wordpress.com/category/ajgenesis/

Angel “Java” Lopez
http://www.ajlopez.com/en
http://twitter.com/ajlopez

October 20, 2008

State Machines in C# 3.0 Using AjGenesis Templates

Filed under: .NET, AjGenesis, Code Generation — ajlopez @ 8:18 am

Recently, I found a code generation scenario, written by Andrew Matthews:

Permanent Link to State Machines in C# 3.0 using T4 Templates

I took the example, and reimplemented it using my code generation project AjGenesis. To run this example, you have to download the published 0.5 version, from Codeplex project page.

(more info about AjGenesis in my previous posts).

The code for this example.

The model is the same of Andrew’s original post:

<?xml version="1.0" encoding="utf-8" ?> <StateModels> <StateModel ID="My" start="defcon1"> <States> <State ID="defcon1" name="defcon1"/> <State ID="defcon2" name="defcon2"/> <State ID="defcon3" name="defcon3"/> </States> <Inputs> <Input ID="diplomaticIncident" name="diplomaticIncident"/> <Input ID="assassination" name="assassination"/> <Input ID="coup" name="coup"/> </Inputs> <Transitions> <Transition from="defcon1" to="defcon2" on="diplomaticIncident"/> <Transition from="defcon2" to="defcon3" on="assassination"/> <Transition from="defcon3" to="defcon1" on="coup"/> </Transitions> </StateModel> </StateModels>

(Andrew wrotes that it is a bit “24 (TV Series)” oriented example… ;-)

I modified Andrew’s solution:

Now, there is an Model.xml file containing the above file. MyStateModel.cs is automatically generated from the model. I changed the solution to have have a Pre-Build event in TestHarness project:

$(ProjectDir)..\VsMakeStates.cmd

The .cmd file contains:

cd ..\..\..
c:\ajlopez\ProyectosNet2\AjGenesis-0.5\bin\AjGenesis.Console TestHarness\Model.xml GenStates.ajg

(You MUST change the second line to point to the AjGenesis 0.5 distribution directory)

With this command, AjGenesis.Console loads the .xml file model, and applies a task, GenStates.ajg, written in AjBasic:

for each StateModel in StateModels
    TransformerManager.Transform(“State.tpl”,”TestHarness\${StateModel.ID}StateModel.cs”,Environment)
end for

There is another command, you can launch from the command line, MakeStates.cmd, containing:

c:\ajlopez\ProyectosNet2\AjGenesis-0.5\bin\AjGenesis.Console TestHarness\Model.xml GenStates.ajg

I love my AjBasic template GenStates.ajg (fragment):

using System; using System.Collections.Generic; using Aabs; using Core; namespace ${StateModel.ID} { public enum ${StateModel.ID}States : int { <# sep = "" for each State in StateModel.States #> ${sep}${State.ID} // ${State.name} <# sep = "," end for #> } // end enum ${StateModel.Id}States ...

It’s based in the .tt file from Andrew Matthews. Note that there is no reference to .XML nodes or similar. AjGenesis loads the model in memory, as a dynamic object. AjBasic language can access to that model, using it as an usual object. The use of ${ } replaces the output with some value, from the variables or from the model in process.

The main point in this example is that it’s based on a free model (AjGenesis can load any model, it’s not use a predefined one). If you want to add more info, you can write more attributes, elements, in .xml file. And use them from the template code.

Another main point: it could be modified to generate the full VS solution, or to generate a solution in other languages (an example generating a full VS solution:
Code Generation for LINQ and C# 3.0 with AjGenesis
)

Thanks to Andrew for such interesting example. You can read more about his implementation in the mentioned post:

Permanent Link to State Machines in C# 3.0 using T4 Templates

Angel “Java” Lopez
http://www.ajlopez.com/en
http://twitter.com/ajlopez

October 2, 2008

Another model for AjGenesis

Filed under: AjGenesis, Code Generation — ajlopez @ 1:14 pm

This post describes an idea, there is no implementation yet. AjGenesis, my open source code generation project, is based in models, tasks and template. Each artifact is used defined, so you can generate outputs for any technology, framework or platform.

The model resides in memory, during the process. You can load many models at the same time: in the provided examples, an abstract model (describing the solution to generate) and a technology model (defining the language, technology, database to use), are both used in the same process.

The model can be loaded from XML files, or from text files (this is a new feature I published recently, under testing). Now, I want to propose another way: model in Excel/spreedsheets files.

The example

In a recent post:

Textual model for code generation in AjGenesis

I presented a simple model, in two representations: XML and textual. That model could be expressed in an Excel spreadsheet as:

 

The scope of an object description is determined by the indent: Entity Customer is an element of Entities. You can use a table to describe an element with multiple elements. A simple property can be described in two consecutives columns: first columm has the property, second one has the value. If you want to describe an object in another worksheet, [..] has the name of the worksheet where the rest of description resides, as in “Entity [Employee]“:

 

The main benefit for this model is the clear presentation you can achieve. Colors and fonts will be ignored when AjGenesis loaded the model. But the presentation is improved. 

Next steps

If this proposal is found useful by users, I could write the new model builder from Excel files. I have to choose what library to use: I could use the Excel object model provided by the tool. Any comments, suggestions?

Angel “Java” Lopez
http://www.ajlopez.com/en
http://twitter.com/ajlopez

September 30, 2008

Code Generation for LINQ and C# 3.0 with AjGenesis

Filed under: .NET, ASP.NET, AjGenesis, C Sharp, Code Generation — ajlopez @ 8:18 am

AjGenesis, my open source code generation project, uses a user-defined model. You can define tasks and templates, to transform the model to code and text files. You can write your own model, new tasks and transformation. You can invoke custom code or .NET objects, in the middle of the generation process.

As the model is user-defined, the system is not limited to one kind of projects. It’s based in templates and tasks, and then, the generated text artifacts are not bound to only one technology. You can generate files for any technology, framework, line of business and platform. You can generate DDL scripts, or a full base application, or anything between. It’s your decision.

When I began to write and use the system, .NET 2.0 didn’t exist. When the new technology became public, I wrote additional tasks and templates to take advantage of new features, as master pages, themes and new ASP.NET controls, without touching the core code of the AjGenesis project. Once the new templates and tasks were written, the project began to generate web applications for ASP.NET 2.x.

Now, as a proof of concept, I wrote a new example, that generates code using LINQ, the new kid on the microsoft block for .NET 3.x. The result was published as AjGenesisExamplesNet3.zip in the page AjGenesis Examples in CodePlex. To run the example, you need the current release 0.5 (includes source code, initial examples, an binaries). (There is a new version under development in the code repository).

The example

There is only one model in the example folders: AjFirstExample, with a simple XML model describing two plain entities, Customers and Suppliers. It’s the same model I used in previous examples.

<Project> <Name>AjFirstExample</Name> <Description>First Example using AjGenesis</Description> <Prefix>AjFE</Prefix> <Domain>com.ajlopez</Domain> <CompanyName>ajlopez</CompanyName> <Model> <Entities> <Entity Source="Entities/Customer.xml"/> <Entity Source="Entities/Supplier.xml"/> </Entities> <Lists> <List Entity="Customer"/> <List Entity="Supplier"/> </Lists> <Forms> <Form Entity="Customer"/> <Form Entity="Supplier"/> </Forms> <Views> <View Entity="Customer"/> <View Entity="Supplier"/> </Views> </Model> </Project>

Templates folder contains two sets of .tpl files (AjGenesis templates). MsSql templates are used in DDL script generation. Inside CSharp3 folder, there are new templates that generates LINQ DataContext, and simple classes.

Running the example

In the main directory, there is a command file

makeajfirstexample.cmd

that loads the model in memory, technology model, and execute two tasks, creating code and DDL scripts.

The solution resides in a new directory, Build, with source code and MS SQL scripts:

Build\AjFirstExample\CSharp3\Sql\CreateDatabase.sql creates database and table, fragment:

create database AjFirstExampleNet3 go ... use AjFirstExampleNet3 go ... -- -- Entity: Customer -- Description: Customer Entity -- if exists (select name from sysobjects where name = 'Customer' and type = 'U') drop table Customer go create table Customer ( [Id] [uniqueidentifier] not null CONSTRAINT [DF_Customer_id] DEFAULT (newid()), [Name] nvarchar(200), [Address] nvarchar(2048), [Notes] nvarchar(2048) CONSTRAINT [PK_Customer] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) go

The solution can be loaded in VS2008:

AjFirstExampleDataContext.cs is a simple LINQ DataContext:

public partial class AjFirstExampleDataContext : System.Data.Linq.DataContext { public AjFirstExampleDataContext() .... public Table<Customer> Customers; public Table<Supplier> Suppliers; }

 

You can replace this DataContext by one generated via Linq To SQL wizard, in Visual Studio. There is an option in the technology model to specify the generation of this custom DataContext. But you can drop it, and replace by a more complete DataContext: the project will compile with both approach.

The solution has three projects: data, services and ASP.NET presentation. The initial page is spartan (you know, I’m a developer, not a graphic designer… :-) ):

From Administration option, you can browse, add, edit and delete customers and suppliers:

 

Next steps

I want to convert other previous examples to this new templates (AjTest model is the more challenging, with one to many relations and many entities). It could be interesting to generate ASP.NET MVC pages, instead of plain ASP.NET. And some testing infrastructure. I’m taking the code of ScrumLite solution as a base example to follow.

Angel “Java” Lopez
http://www.ajlopez.com/en
http://delicious.com/ajlopez
http://twitter.com/ajlopez

September 28, 2008

Textual model for code generation in AjGenesis

Filed under: AjGenesis, Code Generation — ajlopez @ 4:41 pm

I was working adding a feature to my code generation project AjGenesis. The system manage a user-defined model, that can be loaded from .xml files. AjGenesis can process the model, completing it, invoking .NET objects, creating directories, files, and applying templates to create code and text artifacts.

But the model resides in memory: the deserialization from XML is only a choice of implementation. I’ve committed the new work in the source repository at Codeplex: now, every AjGenesis user can express his/her model in plain text

Now, a model can be expressed in simple text files. Let explore an example.

The simplest example I can imagine is a model for a Hello World application in AjGenesis. The model in XML is like:

<Project Company="ajlopez.com"> <Message>Hello, World</Message> </Project>

Now, you can express the same model in a text file:

Project Company = "ajlopez.com" Message = "Hello, World" End Project

If you need more message, you write in XML:

<Project> <Messages> <Message>Hello, World One</Message> <Message>Hello, World Two</Message> <Message>Hello, World Three</Message> </Messages> </Project>

but in text, the same model could be expressed as:

Project Messages Message = "Hello, World One" Message = "Hello, World Two" Message = "Hello, World Three" End Messages End Project

You can load the model from the console line indicating a .txt or .xml file:

..\..\..\bin\AjGenesis.Console Model.txt ModuleVb.tpl HelloWorld.vb

..\..\..\bin\AjGenesis.Console Model.xml ModuleVb.tpl HelloWorld.vb

You can explore more examples at:

Hello world Examples

In a more realistic model, you can express entities in XML:

<?xml version="1.0" encoding="utf-8" ?> <!-- An Entity with Properties --> <Entities> <Entity Name="Customer"> <Description>A Customer</Description> <Properties> <Property Name="Id" Type="Id"/> <Property Name="Name" Type="Text"/> <Property Name="Address" Type="Text"/> </Properties> </Entity> <Entity Name="Supplier"> <Description>A Supplier</Description> <Properties> <Property Name="Id" Type="Id"/> <Property Name="Name" Type="Text"/> <Property Name="Address" Type="Text"/> </Properties> </Entity> </Entities>

or from text (it’s not the same model):

Entities Entity Customer Description = "Customer Entity" Properties Property Id Type="Id" Property Name Type="Text" Property Address Type="Text" End Properties End Entity Entity Supplier Description = "Supplier Entity" Properties Property Id Type="Id" Property Name Type="Text" Property Address Type="Text" End Properties End Entity End Entities

Once the model is loaded in memory, AjGenesis process it as usual, without regarding its original form, text or XML.

More about AjGenesis:

Posts about AjGenesis (English)
Posts sobre AjGenesis (Spanish)

Loosely related, but interesting:

Problems for Textual Model Notations

Angel “Java” Lopez
http://www.ajlopez.com/en

August 18, 2008

Top ten code-generation rules

Filed under: AjGenesis, Code Generation, Software Development — ajlopez @ 7:52 pm

Everyone can recognize me as a die-hard code-generation fan, with a twist: use a model as the starting point. I adopted the idea every week, practicing “dog fooding”, using my own code generation project AjGenesis. This week, I’m reading the now classic book “Code Generation in Action“ , by Jack Herrington, edited by Manning. This book is a “must be read” to everyone interested in code generation. It’s a very interesting reading for developers, but also to managers: the author makes the case for use code generation, appealing to increasing quality and productivity, including agile teams.

In the first chapter, Herrington lists top ten rules I want to comment in this blog. The indented paragraphs are textual excerpts from the book (section 1.7), followed by my own comments:

Give the proper respect to hand-coding

You should both respect and loathe handwritten code. You should respect it because there are often special cases integrated into code that are overlooked with a cursory inspection. When replacing code you’ve written by hand, you need to make sure you have the special cases accounted for. You should loathe hand-code because engineering time is extremely valuable, and to waste it on repetitive tasks is nearly criminal. The goal of your generator should always be to optimize the organization’s most valuable assets—the creativity and enthusiasm of the engineering team.

Yes, the basis of code generation is to make easy to delegate the repetive tasks to the machine. We have to use tools that make easier our work: that’s the reason we are using compilers nowadays, instead of switching the bits directly in memory (or setting the relays in the old Eniac). Code generation rationale is not to destroy the handwritten code: its mission is to support it.

Handwrite the code first

You must fully understand your framework before generating code. Ideally, you should handwrite a significantly broad spectrum of code within the framework first and then use that code as the basis of the templates
for the generator.

Absolutely yes. Sometimes, new users of AjGenesis begin to use it directly from the examples. That is good, but it would be better to generate an example using the framework and technology they uses. If you know how to program using Struts/Hibernate, then, you can separate the variations from the essentials. At that point, you can begin to write the code generation artifacts (templates, tasks).

Control the source code

I can’t stress enough the importance of having a robust source-code control system. This is critical to a successful code-generation project. If your generator works directly on implementation files that contain some hand-written code, make sure you have a versioning system running that can protect your work.

Another path: if you generate the code from a model, check in only the model. The rest of the artifacts will come from code generation process. With the current technology, you can’t generate ALL the solution, but you can separate, with care, the generated part from the manual one.

Make a considered decision about the implementation language

The tools you use to build the generator do not have to be the same tools you use to write the application. The problem that the generator is trying to solve is completely different from the problem being solved by the application. For that reason, you should look at the generator as an independent project and pick your tools accordingly.

That is one of the reasons that supports my adoption of a new language (affectionately named AjBasic) for my code generation tool AjGenesis. I wanted a dynamic language under my control, to extend in any direction the code generation process requires. In one of my initial test, I tried PHP, but I prefer to have a dedicated language.

Integrate the generator into the development process

The generator is a tool to be used by engineers; thus, it should fit cleanly within their development process. If it is appropriate, it can integrate with the integrated development environment (IDE), or in the build process or check-in process.

Making the core of AjGenesis as a class library, it could be integrated to other tools. You can use from NAnt, for example. An IDE tool calling AjGenesis is a pending task.

Include warnings

Your generator should always place warnings around code that it generates so that people do not hand-tweak  the code. If they hand-tweak the code and rerun the generator, they will lose their revisions. In addition, your first response to people ignoring the warnings should be to help them and not to berate them. The fact that  they are using your tool is a big step. Learn why they needed to ignore the warnings and improve  the generator or the documentation. You are the emissary of your tool.

In AjGenesis, this issue is the concern of the templates the user writes. You can add any text you like: that’s the power of writting your own templates, you have the ownership of the generated code.

Make it friendly

Just because a generator is a tool for programmers doesn’t mean it gets to be rude. The generator should tell the engineer what it’s doing, and what files it has altered or created, and handle its errors with a reasonable amount of decorum. It may sound silly, but a tool that is difficult to use or that’s flaky will be ignored and your efforts will be wasted.

AjGenesis core is a dll, that can be invoked from any application. Years ago, I wrote tasks to use it from NAnt. Thanks to Jonathan Cisneros, we have now the AjGenesis Studio, since last year. I improved the original code at the beginning of 2008, adding AjGenesis Web Studio. The error handling must be improved, specially for new users of AjBasic.

Include documentation

Good documentation is a selling point for the generator. Your documentation should be thorough but not overwhelming, and should highlight the key points: what the generator does, how it is installed, how it is
run, and what files it affects.

Actually, is a point not very covered by AjGenesis. But in exchange, there are many blog posts explaning the process, ideas, and examples (AjGenesis posts) (AjGenesis posts in Spanish). Users of the tool are beginning to write too (read Carlos Marcelo Santos posts). There is an Spanish email list where the users can discuss the tool (Code Generation group). And in the Codeplex project page, there are examples for Java, .NET, and PHP, many of these using the same model (the litmus test).

Keep in mind that generation is a cultural issue

Educating your colleagues through documentation, seminars, and one-on-one meetings is critical to successfully deploying the generator. People are skeptical of new things, and a good programmer is twice as skeptical as the average person. You need to break through those concerns and doubts and emphasize that you designed the generator for their benefit.

I gave three to four speech by year, only dedicated to explain the tool and its potential. Additionaly, I explain the tool in every course I give (Java, .NET, PHP, or software development in general). But to be adopted in a company or project, a power user must became the champion of the tool. It’s not easy to raise the level of abstraction, write the model and its transformation, in the middle of the day to day work.

Maintain the generator

Unless the generator is just a temporary measure, it will need to be maintained long term. If the generator manages a large portion of code, treat it just as you would an engineer maintaining that same piece of code. Your budget should include dedicated time and money for maintaining and upgrading that resource.

AjGenesis is not the “things” to maintain. They are the templates and tasks you use in your work. If you adopt the tool to generate .NET applications, you have to change and improve the templates when new tech appears (LINQ, ASP.NET MVC….). And when you gain experience, you have to improve the model itself, if you discover new ways to represent the product lines your company are involved.

I could add some points more:

- The generated code generated must be the kind of code you are proud to write by yourself. The tools should not dictate the form and appearance of such code.

- The use of a model raise the level of abstraction. Such strategy separates the wheat from the chaff, put the technicalities in the place they deserve: the importance is in the model

Well, enough for now. As you can notice, code generation is one of the subject that passionate me. It’s not the silver bullet. But it is a bullet I want to have, just in case.

Angel “Java” Lopez
http://www.ajlopez.com/en

August 12, 2008

Code Generation for NHibernate using AjGenesis

Filed under: .NET, AjGenesis, Code Generation, NHibernate — ajlopez @ 8:23 am

Last year, thanks to the initial idea from Omar del valle Rodriguez, and suggestions of Fabio Maulo, I wrote tasks and templates in my open source code generation tool, AjGenesis, to generate an example of a .NET application, using NHibernate. It shows the use of NHibernate from .NET, using .hbm mapping files (one per class). It generates four applications, two in Visual Basic .NET 2.x, and two in C# 2.0, using DAOs and DDD ideas

The example can be downloaded from the AjGenesis example page at Codeplex. The file is named AjOmar-v1.1.zip.

If you are new to AjGenesis, I wrote some introductory posts:

Code Generation with AjGenesis- A Hello
Application Generation using AjGenesis
Code Generation as a Service with AjGenesis
More post about AjGenesis…

The model

The base idea in AjGenesis is to use a free-defined model, where you can specify what you want to express for your domain at hands. In this example, I model entities, and from such model, AjGenesis generates complete applications, that you can modify and improve. The model is written in XML files, part of the model is at file Projects/AjOmar/Project.xml:

<Project> <Name>AjOmar</Name> <Description>Example AjOmar for (N)Hibernate</Description> <Prefix>AjOm</Prefix> <Domain>com.ajomar</Domain> <CompanyName>ajomar</CompanyName> <Model> <Entities> <Entity Source="Entities/Client.xml"/> <Entity Source="Entities/Company.xml"/> <Entity Source="Entities/User.xml"/> </Entities> </Model> </Project>

Omar initial project have Company and User , both inheriting from Client. In the database, there are three tables, and NHiberate’s magic is in charge of mapping that entity domain to the corresponding tables.

The User.xml describe the user, according to Omar specifications:

<Entity> <Name>User</Name> <Description>User Entity</Description> <SetName>Users</SetName> <Descriptor>User</Descriptor> <SetDescriptor>Users</SetDescriptor> <SqlTable>users</SqlTable> <Inherits>Client</Inherits> <Properties> <Property> <Name>FirstName</Name> <Type>Text</Type> <SqlType>varchar(200)</SqlType> </Property> <Property> <Name>LastName</Name> <Type>Text</Type> <SqlType>varchar(200)</SqlType> </Property> </Properties> </Entity>

The User entity inherits from Client, described as:

<Entity> <Name>Company</Name> <Description>Company Entity</Description> <SetName>Companies</SetName> <Descriptor>Company</Descriptor> <SetDescriptor>Companies</SetDescriptor> <SqlTable>companies</SqlTable> <Inherits>Client</Inherits> <Properties> <Property> <Name>CompanyName</Name> <Type>Text</Type> <SqlType>varchar(200)</SqlType> </Property> <Property> <Name>ContactName</Name> <Type>Text</Type> <SqlType>varchar(200)</SqlType> </Property> </Properties> </Entity>

There are technology elements, in separate files, as database to use, the language to generate, and other details. So, we can change the technology details without changing the above abstract model. An example of a technology file is Projects/AjOmar/Technologies/VbNet2Nh.xml:

<Technology> <Programming> <Dialect>VbNet2Nh</Dialect> </Programming> <Database> <Dialect>MsSql</Dialect> <Name>AjOmar</Name> <Username>sa</Username> <Prefix>ajom_</Prefix> <Host>(local)</Host> </Database> <NHibernate> <Dialect>NHibernate.Dialect.MsSql2000Dialect</Dialect> </NHibernate> </Technology>

You can change this file to your convenience. Following Fabio Maulo suggestion, there is one .hbm per entity. Using AjGenesis templates and tasks, this is an example of such mapping file, Build/AjOmar/VbNet2Nh/Src/AjOmar.Data/Company.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="AjOmar.Entities" namespace="AjOmar.Entities" > <joined-subclass name="Company" table="ajom_companies" extends="Client"> <key column="Id" /> <property name="CompanyName" type="String"/> <property name="ContactName" type="String"/> </joined-subclass> </hibernate-mapping>

The applications

The example generate complete applications, with class library projects and web site to use as presentation layer. The code generation process is invoked from command line, using this four commands from AjOmar folder:

GenerateProject AjOmar VbNet2Nh
GenerateProject AjOmar CSharp2Nh
GenerateProject AjOmar VbNet2DDDNh
GenerateProject AjOmar CSharp2DDDNh

You must add the AjGenesis bin folder to your path. The first two commands generate ASP.NET 2.x applications, in VB.NET and C#, using DAOs that invoke NHibernate. Additionaly, they generate the DDL scripts to create the MS SQL Server database. The last two are similar, but using some ideas from Domain-Driven Design. This is tipical output of the tool:

Under the build folder the applications are generated:

This is the C# application loaded in Visual Studio:

The Web client project implements a navigational model to browse and update entities.

Note: the model is not fixed. You can define the model as you want. This is an example only to show AjGenesis capabilities. But you can write your own model, transformations and templates. AjGenesis is not limited to one predefined model, and you can generate all the text artifacts you want, if you write the corresponding tasks and templates. Sky is the limit!

Generating DDD

There are solutions using DDD ideas. They have class library projects:

  • AjNHibernate: containing the classes to call NHibernate: configuration, session factory, and session management.
  • AjOmar.Domain: Entities, Services, Repositories, a la Evans. There is no Value Objet or Aggregate The services are called Managers: the name service is used in Application project.
  • AjOmar.Application: the tier that coordiname the calls to Domain, from presentation.

There is a web application, AjOmar.WebClient, with pages to list, view and update entities:

Next steps

The idea is to expand this example to generate code that uses Hibernate, Java, EJB3, MySql, and/or Struts2. I have some examples written, but I have to update them to the ideas presented by Omar and Fabio. Code generation for other technologies is the acid test for AjGenesis: from the same model, generate different applications with many technologies. Suggestions, comments, welcome!

Angel “Java” Lopez
http://www.ajlopez.com/en

April 23, 2008

AjGenesis: Generating the model from assemblies

Filed under: .NET, AjGenesis, Code Generation — ajlopez @ 10:28 am

 Darío Quintana have rewrote his program that generates an  AjGenesis model starting from compiled .NET assemblies. The last version is described at (Spanish post):

Generando con AjGenesis desde los assemblies

The image shows the main project directory content. There are other projects, with NUnit tests, examples, and compiled code.

It is interesting to see how a model (there is no fixed model in AjGenesis) could be obtained from different sources. In a previous post I described a short example, showing how to obtain a model from the database structure:

AjGenesis: Generating the model from the database

Darío, in his post, shows how he uses his project from an AjGenesis tasks:

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

This code uses the new AssemblyManager to load the library AjGenesis.FromAssembly.

The classes Model, Entity, Property are the model, like in other AjGenesis examples. The class Collector creates a Generator object. This object is in charge of the hard work, finding the entities inside an assembly:

using System.Collections; namespace AjGenesis.FromAssembly { public class Collector { public ArrayList GetEntities(string assemblyPath, string ns) { Generator g = new Generator(); g.Path = assemblyPath; g.AssemblyToObjects(); ArrayList array = new ArrayList(); foreach (Entity entity in g.Model.Entities) { array.Add(entity); } return array; } } }

Un fragmento de Generator:

 

public void AssemblyToObjects() { Assembly assembly = Assembly.LoadFrom(Path); Type[] types; types = assembly.GetTypes(); //Get all types from the assembly for (int i = 0; i < types.Length; i++) { //Veo que interfaces está implementando bool ImplementaIEntity = false; Type[] interfacesTypes = types[i].GetInterfaces(); ImplementaIEntity = true; if (ImplementaIEntity) { Entity entity = new Entity(); entity.Name = GetTypeName(types[i].Name); entity.FullName = types[i].FullName; if (types[i].BaseType != null) { entity.Inherits = GetTypeName(types[i].BaseType.Name); entity.InheritsFullName = types[i].BaseType.FullName; } PropertyInfo[] propertyInfo = types[i].GetProperties(); foreach (PropertyInfo pi in propertyInfo) { Property prop = new Property(); prop.Name = pi.Name; prop.TypeName = pi.PropertyType.Name; if (pi.PropertyType.FullName != null) { prop.TypeFullName = pi.PropertyType.FullName; } else prop.TypeFullName = string.Empty; entity.Properties.Add(prop); } _model.Entities.Add(entity); } } }

This is only a fragment of the code, see the complete project to have more detail. It uses reflection to obtain the types in an assembly, and its properties. I guess Darío wants to improve the way of detecting when a type is an entity, using interfaces and attributes.

Angel “Java” Lopez
http://www.ajlopez.com/

Older Posts »

Blog at WordPress.com.