Last time, in Part II, I described a highly structured approach to creating and harnessing a preprocessed template to generate a simple C# class from metadata. I put lots of nice extensibility points in that template and now we’re going to exploit them to show how easy it gets to be to customize a template once you have such a structure in place.
Here’s an edited reminder of the code we wanted to generate:
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: … More methods elided …
41:
42: }
We’d like all of the summary comments to contain a reminder not to edit generated code and we need our class to be marked as internal and Serializable.
If we take a look at the customization points in our base template, DataClass.tt, we’ll see we have what we need. We can override Summary() and ClassHeader() to add the extra text we need:
1: <#+
2: // ---------------------------------------------
3: // Override some of the snippet methods from DataClass.tt to change the template's behavior.
4: // ---------------------------------------------
5:
6: /// <summary>
7: /// Override the summary method to remind readers more regularly that this code is auto-generated by a tool
8: /// </summary>
9: public override void Summary(string comment)
10: {
11: base.Summary(comment);
12: #>
16: <#+
17: }
18:
19: /// <summary>
20: /// Override the class header method to make the generated class partial, internal and Serializable
21: /// </summary>
22: public override void ClassHeader(TypeDescription type)
23: {
24: #>
25: [Serializable]
26: internal partial class <#= type.Name #>
27: <#+
28: }
29: #>