T4

Generate Your WCF Files From Your Spreadsheet

Posted on

Meet your Deadlines with T4 Template Files

Here’s my situation: we’re building an SOA and spending a long time on our design process. We need to revise our methods and parameters repeatedly, and we’re building a lot of methods and classes. We also need to build some documentation (a specification file). We have a tight deadline, so, after we finally finish modifying all those method signatures, we need to quickly build an interface for our B2B partners. It would be really nice if I could build, or rebuild, all those classes from a master definition file!

Solution

  1. Enter all the method definitions in an Excel file
  2. Also enter the data classes and their parameters in the same Excel file
  3. After all the revisions and negotiations, use the data in the Excel file to generate the code files using T4 templates
  4. Also generate the spec file using the same process

Remarks

I built a project using T4 templates to generate my code files. Note that the data contract files for WCF are mostly boiler plate, but it is still a lot of work. I can use the results to build WSDL in a few seconds. The benefits is that our B2B partners can code against that WSDL immediately, and I can update it easily.

I’m quite happy with the results. Running the app is easy, and there are no issues like improper casing for names or inconsistent spellings. Plus, when we make changes, the spec file can be immediately regenerated and be completely consistent with the code. Furthermore, it easy to write the my code generator; actually I built a working prototype one afternoon.

ScreenShot
Screen shot showing the inputs to generate the classes. The namesapces and other textboxes are auto-suggested from reading the master definition file.
All these classes were created in a split second when I clicked the button. They define the guts of a WCF web service.
I generated all these classes in a split second by clicking the button. They define the guts of a WCF web service. As mentioned above, the data classes are mostly boiler plate, the service contract (interface 100% usable straight from auto-generation)  and we can customize the service file as necessary.

,

How it Works

You can add a T4 Template file to any .NET project. T4 templates are designed for generating code from sources like a master definition file, database file, etc. T4 templates are a mixture of text (payload) and markup (your code that injects varying content). Here’s a sample for my auto-generation project:

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".txt" #>
<#@ import namespace="AutogenerateWCF.SupportingClasses" #>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace <#= NamesapceToUse #>
{
    public class <#= ServiceClassName #> : <#= InterfaceName #>
    {
<# foreach(MethodInfo mi in Methods) { #>
	<#= mi.ReturnType #> <#= mi.Name #>(<#= mi.FormattedParameterList #>){
		return new NotImplementedException();
	}

<# } #>
	}
}

In the sample above, all my markup is in between the tags <# and #>. The markup references class properties on my T4 class. I wrote my T4 class to expose properties called “NamespaceToUse”, “ServiceClassName” and “Methods”. When I use my template (explained in depth below), it generates output that looks like the following:

using System.Runtime.Serialization;
using System.ServiceModel;

namespace B2BWebServcies
{
    public class B2BHPServices : IB2BWebServcies
    {
		GetLocationResponse getLocationServiceCenter(Credential credential, GetLocationServiceCenterRequest request){
			return new NotImplementedException();
		}

		GetInventoryDataResponse getInventoryData(Credential credential, GetInventoryDataRequest Request){
			return new NotImplementedException();
		}
	}
}

 Adding a T4 Template to Your Project

Add a new item to your project; for the type, choose ‘Text Template’:

How to Add a T4 Template to your Porject
How to Add a T4 Template to your Porject


After you add your Template file, change its Custom Tool to ‘TextTemplatingFilePreprocessor’

Select your new T4 file and change its custom tool to 'TextTemplatingFilePreprocessor'
Select your new T4 file and change its custom tool to ‘TextTemplatingFilePreprocessor’

Now, add a partial class with the same class name as your template file. The partial class will hold the properties you will utilize in your markup, such as ‘NamespaceToUse’. Next, populate your markup, injecting class properties where necessary.

To use your template,

  1. Set the class properties using whatever data source you need; in my case, I loaded from my master definition file (exported from Excel)
  2. Invoke your template class’s TransformText method – this returns a string containing your final output!

To learn more, download my sample code here.

Auto-Generate Forms and Class by Reverse Engineering Your Class or Web Reference

Posted on Updated on

Use Reflection with T4 Templates to Instantly Build WPF Forms

Want to meet your deadlines? Want your boss to respect your ability to get work done fast? Then automate your coding process and watch your credibility rise! Your boss willl be impressed with your speed and sophistication.

.NET already generates some data entry forms for you, such as in the ASP.NET MVC framework. But, as far as I know, this only works when your source is database tables, queries or views. That doesn’t help if you want to work with, for example, a web service and send data across the web.

In contrast, I am generating code using reflection. That means you can build a data entry (or display) form based on any dll or exe. That works nicely when you consume Web Services, because Reflection can examine the class structures and build forms, etc.

If you need additional, or special functionality, you are completely free to augment or customize the code I generate, So just your special needs after you do most of the work automatically!

Sample Output

Screen Shot Showing Auto-Generated Form
I generated this form in about 5 seconds. It is data-bound, has a View Model and a code-behind file. I generated the form fields based on the Amazon Web Services class ‘Address’.

 What Gets Generated

  • My code generates the XAML displayed above
  • You also get a ViewModel, if you elect to use MVVM (MVVM is like a Model-View-Controller for WPF),
  • Every TextBox you see above is databound to a field in the ViewModel (again, optional)
  • I also generate a save button with associated MVVM command, but you need to write some codeto perform your save

Besides Running my Code Generator, I Did This:

As I mentioned above, my code uses reflection, so it needs a dll (or exe) to reverse-engineer. For this sample,

  1. I started coding my main project
  2. Added a (Web) Service Reference to Amazon Web Services, to my main project
  3. (which caused Visual Studio to generate data-classes in my project) (but not data entry forms)
  4. Since the code generator needs a dll, I then built my partially completed project to make that dll
  5. Then I switched to my code generator
  6. Browsing for the dll from the first project
  7. Next, I clicked a button to generate the code shown above
  8. And saved it to file
  9. Finally, I switched back to my original project and added the new code that I just built!
Screen shot showing assembly and type selection
Screen shot from my code generator, showing where I picked the dll to reverse-engineer. After picking the dll, I then picked a class inside that dll, which contains the fields for my form.

Next, I specify some options to use when generating my code:

Screen shot showing code generation options
My code generator allows you to specify options like namespace, class name and field sequence.

Next, I generate the code, and modify it, if desired. When happy, I click the save button.

Screen shot showing generated code
When I click the ‘Generate’ button, the code is displayed. You can modify it if desired, then save to file. After saving, you can add it to your original project

How does it Work?

I demonstrated some features of Reflection in a previous post, “Make Debugging Easier with My Complex Object Visualizer“. If you read that post, you know that you can get class properties using reflection like this:

//'selectedType' is, in my sample, the Address class Type, hard-coded here
Type selectedType = typeof(Address);
PropetyInfo[] props = selectedType.GetProperties(BindingFlags.Public 
                                 | BindingFlags.DeclaredOnly | BindingFlags.Instance);

Now my array ‘props’ has all the properties form the Address class, such as ‘Street1’ or ‘City’.

You can also use reflection to load an assembly at run time, as shown below:

string fName = "OrderLib.dll";
Assembly targetDll = System.Reflection.Assembly.LoadFrom(fName);
//Then I can get all the Types (classes) and let you pick which to use:
Type[] targetTypes = targetDll.GetTypes();

If you download my code (bottom of the post), you can see some other Reflection features I utilized.

A Brief Explanation of T4

T4 is the code generation library included in Visual Studio. It is actually quite easy to use, particularly if you are familiar with ASP.NET. It is a mixture of markup and code. Microsoft has some easy, yet useful, tutorials here: http://msdn.microsoft.com/en-us/library/bb126445.aspx. The excerpt below (from my T4 Template file) shows how I generate the code behind file:

<#@ template language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
using System;

namespace <#= _NameSapceToUse #> {
    public partial class <#= ClassNameToUse #> : Window {
        public <#= ClassNameToUse #>() {
            InitializeComponent();
            this.DataContext = new <#= ViewModelClassName #>();
        }
    }
}

The highlighted portions are injected with values from my code, when I generate my code. Anything outside <# #> brackets is just text that is copied into the output. The equals sign (inside the <# #> brackets) signifies to copy a class property from my T4 class.

You can also use loops inside a T4 Template, as illustrated in the fragment below:

<# for (int i = 0; i < _ClassProps.Count; i++) { #>
    <Label Grid.Row="<#= i #>" Grid.Column="0" Content="<#= _ClassProps[i].Key #>" Target="{Binding ElementName=txt<#= _ClassProps[i].Key #>}" />
    <TextBox Grid.Row="<#= i #>" Grid.Column="1" Name="txt&lt;#= _ClassProps[i].Key #>" Text="{Binding <#= _ClassProps[i].Key#>}" />
<# } #>

The sample above shows a loop, inside a T4 template; it generates a Textbox and label for every entry in my list ‘_ClassProps’. As you can see, I wrote a ‘for loop’ here, but you can insert any other code you need.

Three Tips for Using T4

  1. When you add a T4 template to your class (with file extension ‘.tt’), change its custom tool to ‘TextTemplatingFilePreprocessor’
Set the CustomTool property as shoown
Set the CustomTool property as shoown above. Note: I have to add a text file, then change the file extension.

2.) Add a new class file to your project and make it a partial class, with the same name as your T4 class. This is how you add custom properties to your T4, such as the _ClassProps list you saw used above. The properties/fields in your partial class are visible in the template.

3.) When you are ready to generate your code, invoke the ‘TransformText’ method on an instance of your class, as shown below:

WpfFormGen myGen = new WpfFormGen(classProps, GeneratedNamespace, GeneratedFormName, ShouldGenerateViewModel.Value);
string theWindow = myGen.TransformText();
GeneratedXaml = theWindow;

Caveat

This is not a commercial product, and I only spent a few days developing it. It could do a lot more, or you could download the code and tweak it yourself. Also, you aren’t allowed to sell my code or claim it as your own!

Moving Forward

My code generate creates WPF forms, suitable for use with the MVVM style of development, because I am familiar with that style of coding. But, there is nothing to stop you from writing similar code to generate, for example, ASP.NET code. Why? Because it is nice to generate code from dlls, not being limited to database tables. But! There is nothing stopping you from using T4 to generate forms from tables (if you aren’t using ASP.NET MVC).

Next, I may re-write my project to generate AngularJS javascript, because I am learning it now. So far, I have found that AngularJs is case-sensitive and very picky, so generating the code automatically would make it less painful by getting the proper case.

I may also elect to re-write the project as a Visual Studio Add-in.

Download the code here