State Machines in C# 3.0 Using AjGenesis Templates

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:


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
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} // ${} <# 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

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s