Wednesday, May 6, 2009

Built-in Visual Studio 2008 Code Generator

Have you ever heard about code generator built-in VS 2008 by default? Microsoft named it "T4: Text Template Transformation Toolkit". It is integrated into Visual Studio and very easy to use. Let me demonstrate it on example.

Let us suppose we need a class with methods like those for such primitive types as Int32, Double, Decimal, DateTime, TimeSpan and other.

  public static Double ParseDouble(string value)
  {
    if (value == "Default")
      return default(Double);
    if (value == "MinValue")
      return Double.MinValue;
    if (value == "MaxValue")
      return Double.MaxValue;
    return Double.Parse(value);
  }

  public static Double? ParseNullableDouble(string value)
  {
    if (value == "Default")
      return default(Double);
    if (value == "MinValue")
      return Double.MinValue;
    if (value == "MaxValue")
      return Double.MaxValue;
    if (value == "Null")
      return null;
    return Double.Parse(value);
  }


Because it isn't very interesting to implement it manually I suggest to use built-in code generator. How we can do this:

1. Create class SmartParser.cs and implement those methods for one type, e.g. for Int32
2. Rename SmartParser.cs to SmartParser.tt
3. Now it is possible to use ASP.NET-like tags <# #> and <#= #> to generate this code for all types we need and Visual Studio will automatically create file SmartParser.cs

In our case SmartParser.tt will look like this:

using System;

public static class SmartParser
{
<#
Type[] types = new Type[] {
  typeof(Int32),
  typeof(Double),
  typeof(Decimal),
  typeof(DateTime),
  typeof(TimeSpan)
};
foreach (Type type in types) {
#>

  public static <#=type.Name#> Parse<#=type.Name#>(string value)
  {
    if (value == "Default")
      return default(<#=type.Name#>);
    if (value == "MinValue")
      return <#=type.Name#>.MinValue;
    if (value == "MaxValue")
      return <#=type.Name#>.MaxValue;
    return <#=type.Name#>.Parse(value);
  }

  public static <#=type.Name#>? ParseNullable<#=type.Name#>(string value)
  {
    if (value == "Default")
      return default(<#=type.Name#>);
    if (value == "MinValue")
      return <#=type.Name#>.MinValue;
    if (value == "MaxValue")
      return <#=type.Name#>.MaxValue;
    if (value == "Null")
      return null;
    return <#=type.Name#>.Parse(value);
  }
<#
}
#>

}


Now we can open automatically generated SmartParser.cs just to ensure, that everything is OK and our "huge" class is successfully generated (-;

You can generate not only *.cs files, but *.xml, *.txt, *.html and generally text files with any extension. There are also several useful directives, for example:

<#@ output extension="txt" #>
<#@ template language="C#v3.5" #>
<#@ import namespace="System.Linq" #>
<#@ assembly name="System.Core" #>


Any additional information on T4 can be easily found оn the web.

7 comments:

  1. Very nice, thanks for the heads up.

    ReplyDelete