In order to explore Preprocessed Text Templates a bit further, this post shows a small example using this new feature in a simple code generator. The basic ideia is to:
- Create a “generic” code generation project that transforms a list of customers (the model) into a comma-separated text file, using preprocessed text templates.
- Create a test project that enables viewing the transformation results.
Step 1: Create the Code Generator project
Run VS2010, select File | New | Project. Select Visual C# | Class Library and name the project CustomerCodeGenerator.
Step 2: Add the model class
Rename Class1.cs to Customer.cs. Add 3 public properties of type string: Name, Address and Phone.
namespace CustomerCodeGenerator { public class Customer { public string Name { get; set; } public string Address { get; set; } public string Phone { get; set; } } }
Step 3: Add the template
Add a new preprocessed text template. Name the file CustomerCSVGenerator.tt. Add a new class, name the file CustomerCSVGeneratorCustom.cs. Edit the file and set the class to partial and change it’s name to CustomerCSVGenerator. This is where the model will be set for the code generator – a list of customers.
using System.Collections.Generic; namespace CustomerCodeGenerator { public partial class CustomerCSVGenerator { public List<Customer> Customers { get; set; } } }
Step 4: Add the template code
The template code is quite simple, generate a single comma-separated line for each customer in the list.
<#@ template language="C#" #> <# foreach (Customer customer in this.Customers) { #> <#= customer.Name #>;<#= customer.Address #>;<#= customer.Phone #> <# } #>
Step 5: Add the test project
Select File | Add | New Project. Select Visual C# | Class Library and name the project CustomerCodeGeneratorTest. Add a reference to the CustomerCodeGenerator project.
What’s the best way of quickly viewing the transformation results? A Text Template, of course!
Add a new Text Template named CustomerCodeGeneratorTest.tt. We will use this template to call the transformation class and view the generated output.
<#@ template debug="false" hostspecific="false" language="C#" #> <#@ assembly name="CustomerCodeGenerator.dll" #> <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="CustomerCodeGenerator" #> <#@ output extension=".txt" #> <# List<Customer> customers = new List<Customer>(); customers.Add(new Customer { Name = "Customer1", Address = "Some Street", Phone="123" }); customers.Add(new Customer { Name = "Customer2", Address = "Some Other Street", Phone = "456" }); customers.Add(new Customer { Name = "Customer3", Address = "Yet Another Street", Phone = "789" }); CustomerCSVGenerator generator = new CustomerCSVGenerator(); generator.Customers = customers; #> <#= generator.TransformText() #>
Generated output:
Customer1;Some Street;123 Customer2;Some Other Street;456 Customer3;Yet Another Street;789
Conclusions
This is something that could be achieved with standard templates, by using includes or some other mechanism. However, preprocessed text templates enable a simple and clear way to implement code generators.
- The model can be anything. In this example, a Customer class defines a model that the template “knows”. We can easily read customers from a database, a XML file or some other source and reuse the same code generation class.
- Having the template as a class means that it is not necessary to use TextTransform.exe to automate running the transformations. This way, creating your own transformation tool is quite simple.
The next step is to see how these templates integrate with DSL Models.