I listen to several podcasts. For a complete list see my sidebar. One of these is HanselMinutes
A weekly audio talk show with noted web developer and technologist Scott Hanselman and hosted by Carl Franklin
In reality what this means is that Scott has spend a great deal of time dealing with technology of varying kinds and brings us this weekly show with Carl Franklin (of DotNetRocks fame.) and shares with us his knowledge regarding tools utilities tips and tricks relating to .. well .. almost anything.
Scott recently did a podcast (ok so it was a month or more ago) on Code Generation in which he mentioned several code generation options and rated their capabilities and effectiveness.
As Scott himself points out during the course of his show, there are far more Code-Generation products available then he could possibly have covered during his show.
One that was missed by Scott, but found by my good friend Marc Croom, was MyGeneration a freeware application/framework build around the dotnet framework.
MyGeneration claims to be capable of everything that CodeSmith is and has the added bonus that it's free (although not open-source).
Naturally (given a free framework some spare time to play with) we have begun to delve into the realms of Code-Generation and have been trying to decide just how we can take advantage of it.
MyGeneration comes complete with a framework for reflecting over an existing database structure. So you can create a class per Table/View/StoredProc which can contain constants derived from the Table names, Field names, parameter names and code derived from a combination of these and code pre-build into the template. (Of course these are ideas not limits)
Inside a couple of hours we (Marc and myself) have managed to create a few simple templates which we were then able to use to completely regenerate the existing DAL (Data Access Layer) of one of our company's main applications.
The application in question has, at last count, 122 tables, and 45 views.
Classes for all 167 of these database objects including Select/Insert/Update/Delete methods (obviously where appropriate), relevant fieldname constants and several lazily loaded properties were generated following this in less than 30 seconds
And that was just from the meta data gathered from the database itself.
I can insert this generation of code into my build procedure to ensure that I get compile errors if I change the database to the point where old code cannot work against it.
If I delete a field the code generation will regenerate without that field constant and any code that references it will fail to compile.
In the old days, (lol I'm not that old :)) we would have "hand coded" constants to represent the fields of a database. These constants would have been compiled into the code and would not have manifested problems until runtime.
So here we fail as early as possible moving as many errors as we can from runtime to compile-time.
Hey here's an interesting idea. Hows about we generate assertions for the existence of each and every field and table in our entire data structure which we can run upon application startup in order to determine for certain that we are running against the correct version of the database.
The Next Step
In the current situation, "The Database" is the domain language. In other words the database contains all the information used to perform the generation of code. This is great for simple needs, like mine are currently, but what if later I need to express exceptional circumstances to my templates?
I plan on taking a leaf out of Scott's book and trying the following.
I'm going to try to use MyGeneration to generate, not code, but an XML representation of the schema of my database.
I'm then going to see if I can't knock up an assembly or 2 to help MyGeneration reflect in a strongly typed fashion over the generated XML and see if it's can't be made to generate the SQL Schema from the XML
Initially this might seem like a strange idea, but there is method to my madness.
You see in doing this, I will have shifted my Domain Language from the Database to the XML.
The reason for this, is that XML is capable of having meta-bits added to express things that the database cannot. So I can markup my database XML definition with business information which should enable my code generation to make sensible decisions.
I would like to generate a DAL for my database. But there are several tables for which I would like to generate further logic.
I have a Customer table and a Product table and I would like to indicate to the generation system that it should generate Domain Objects for these tables.
So I would actually like the system to generate Customer and Product objects which would naturally have intellisense access to properties which represent the fields in the table. Further I would like to generate collection classes for these new Domain Objects and finally I would like the DAL for these objects to return collections of these objects rather than Rows, Datasets or Datareaders. So now my results are strongly typed, iterable (not sure that's a word) and I can inherit/amend these to add business-logic.
There is no easy way to markup the database itself so that the templates can understand that these tables are special but I should be able to markup the XML in any way I see fit making this an almost trivial task.
There would seem to be many potential uses for Code-Generation. A few more I have either thought of myself or have had suggested by others include
Unit Tests for generated code
If you can think of any more, then please feel free to let me know in the comments. I'm very interested to know what people are doing in this space.