VS2010 SP1: T4 Template Inheritance Part I – Sample Metadata

We’ve done a bunch of work on T4 in Visual Studio 2010 SP1 to enable template inheritance. 

A reasonable question at this point would be

“Why would you want inheritance in your text templates?”

Well, the typical reason would be the same as with any other code – because you want reuse and extensibility between a family of templates that have some significant similarities.  It’s really nice to be able to customize a template just by overriding a method as you would with any other O-O system.  Oleg Sych has an example of such a system on his excellent blog that works well with previous versions of T4 using nested classes, but I like to think the latest version of T4 makes it all a little bit easier.

I’m going to walk through a couple of examples of using inheritance with a themed sample, so let’s have a look at it.  I’ve previously discussed using simple C# data structures to drive a template.  This time I’ve got a couple of classes to provide metadata for simple data structures:

    1: public class TypeDescription
    2:   {
    3:       public string Name { get; set; }
    4:       public string Description { get; set; }
    5:       public List<TypePropertyDescription> Properties =
    6:                  new List<TypePropertyDescription>();
    7:   }
    8:  
    9:   public class TypePropertyDescription
   10:   {
   11:       public string Name { get; set; }
   12:       public string Type { get; set; }
   13:       public string Description { get; set; }
   14:   }

To keep things simple, a type is essentially jus a named and described bunch of properties. You can imagine using something like this to generate C# DAL classes, SQL schema creation scripts, ORM mappings and other typical application paraphernalia.

Here’s an example of populating the structure:

    1: this.Description = new TypeDescription
    2: {
    3:   Name="Book",  Description="A class to carry data about a book in a library system.",
    4:   Properties=
    5:   {
    6:     new TypePropertyDescription{Name="Title",         Type="string",    Description="The title of the book."},
    7:     new TypePropertyDescription{Name="AuthorID",      Type="string",    Description="The ID of the author of the book."},
    8:     new TypePropertyDescription{Name="ISBN",          Type="string",    Description="The standard ISBN number of the book."},
    9:     new TypePropertyDescription{Name="CopiesOwned",   Type="int",       Description="The number of copies the library owns."}
   10:   }
   11: };

Let’s say I’m going to generate a simple C# class from this metadata and I have a standard template that generates the following class:

    1: /// <summary>
    2: /// A class to carry data about a book in a library system.
    3: /// </summary>
    4: public class Book
    5: {
    6:     /// <summary>
    7:     /// The title of the book.
    8:     /// </summary>
    9:     public string Title { get; set; }
   10:  
   11:     /// <summary>
   12:     /// The ID of the author of the book.
   13:     /// </summary>
   14:     public string AuthorID { get; set; }
   15:  
   16:     /// <summary>
   17:     /// The standard ISBN number of the book.
   18:     /// </summary>
   19:     public string ISBN { get; set; }
   20:  
   21:     /// <summary>
   22:     /// The number of copies the library owns.
   23:     /// </summary>
   24:     public int CopiesOwned { get; set; }
   25:  
   26: }

Now on a new project, I decide that I need my data class to be serializable and that I want regular reminders not to edit the generated code (people don’t pay a lot of attention to the top of the file as it turns out).  I’d like the following:

    1: /// <summary>
    2: /// A class to carry data about a book in a library system.
    3: /// </summary>
    4: /// <remarks>
    5: /// This code generated by the DataClass.tt template - DO NOT MODIFY THIS CODE.
    6: /// </remarks>
    7: [Serializable]
    8: internal partial class Book
    9: {
   10:     /// <summary>
   11:     /// The title of the book.
   12:     /// </summary>
   13:     /// <remarks>
   14:     /// This code generated by the DataClass.tt template - DO NOT MODIFY THIS CODE.
   15:     /// </remarks>
   16:     public string Title { get; set; }
   17:  
   18:     /// <summary>
   19:     /// The ID of the author of the book.
   20:     /// </summary>
   21:     /// <remarks>
   22:     /// This code generated by the DataClass.tt template - DO NOT MODIFY THIS CODE.
   23:     /// </remarks>
   24:     public string AuthorID { get; set; }
   25:  
   26:     /// <summary>
   27:     /// The standard ISBN number of the book.
   28:     /// </summary>
   29:     /// <remarks>
   30:     /// This code generated by the DataClass.tt template - DO NOT MODIFY THIS CODE.
   31:     /// </remarks>
   32:     public string ISBN { get; set; }
   33:  
   34:     /// <summary>
   35:     /// The number of copies the library owns.
   36:     /// </summary>
   37:     /// <remarks>
   38:     /// This code generated by the DataClass.tt template - DO NOT MODIFY THIS CODE.
   39:     /// </remarks>
   40:     public int CopiesOwned { get; set; }
   41:  
   42: }

Next time, I’ll show you how to achieve this customization without substantially modifying the original template.

Technorati Tags: T4,Visual Studio 2010 SP1