Broloco

An Alternative to CodeSmith

I'm a big fan of code-generation for automating boiler-plate code. I used to use CodeSmith for this, but the freeware version is no longer maintained. T4 is my new favourite tool for code generation, and there's a wealth of information available on using it on Oleg Sych's site.

Passing Command-Line Parameters to TextTransform

The tools come with a command-line host for T4 (TextTransform.exe), but there's no obvious way to pass parameters to the templates.

You can pass parameters using the command-line option -a:

TextTransform.exe
    -a mappingFile!c:\myPath\MyClass.hbm.xml
    -out c:\myGeneratedFiles\MyClass_Generated.cs
    c:\myTemplates\GenerateNHibernateProperties.tt
        

In order to retrieve the parameter from inside the template, you can use a little reflection:

private string GetCommandLineProperty(string propertyName)
{
    PropertyInfo parametersProperty =
        Host
            .GetType()
            .GetProperty("Parameters",
                BindingFlags.NonPublic | BindingFlags.Instance);

    StringCollection parameters =
        (StringCollection)parametersProperty
            .GetValue(Host, null);

    foreach (string parameter in parameters)
    {
        string[] values = parameter.Split('!');
        int length = values.Length;
        if (values[length - 2] == propertyName)
            return values[length - 1];
    }
    return null;
}
        

Replacing NHibernate Magic Strings

Now I can loop through my .hbm.xml files in my build, generating the 'magic strings' for the properties of each class (example template and project is linked below).

This turns code like:

IList<Media> mediaWithNameAndType =
 DomainRegistry.Repository
  .CreateQuery<Media>()
  .Add(Expression.Eq("OwningLibrary", this))
  .Add(Expression.Eq("Type", media.Type))
  .Add(Expression.Eq("Name", media.Name))
  .List<Media>();
        

Into code like:

IList<Media> mediaWithNameAndType =
 DomainRegistry.Repository
  .CreateQuery<Media>()
  .Add(Expression.Eq(Media.Properties.OwningLibrary, this))
  .Add(Expression.Eq(Media.Properties.Type, media.Type))
  .Add(Expression.Eq(Media.Properties.Name, media.Name))
  .List<Media>();
        

Some links:

Submit this story to DotNetKicks Shout it

1 comments:

This comment has been removed by the author.