As I mentioned in my last post I've been working with Microsoft Blueprints, one of the problems I encountered was trying to come up with a generic, reusable way of working with T4 Templates (T4 is the used by Blueprints for all code generation as T4 is now integrated into Visual Studio 2008) to generate the code fragments.
I created a T4TemplateBuilder object that exposes a fluent interface to take the pain out of manipulating T4 Templates:
T4Template template = T4TemplateBuilder
.Initialise(context)
.SetTemplateFileName("MyT4Template.tt")
.SetTargetFileName(@"C:\Temp", "MyFolder\MyGeneratedFile.cs")
.SetProperty("MyProperty", "MyValue")
.Transform()
.SaveToFile()
.Finish();
The T4TemplateBuilder parses (using a simple RegExp) any T4 template to dynamically retrieve a list of properties that need to be passed in. I wanted to provide a simple GUI to allow the user to enter values for the T4 Template properties as part of the Blueprint “unfolding” process. Rather than re-inventing the wheel I decided to try and use the PropertyGrid Control.
The data structure used to hold the T4 Template data within the Blueprints Framework is a generic Dictionary: Dictionary<string, Pair<string, Type>>() and unfortunately if you bind this to the PropertyGrid Control, you get the following:
![clip_image002[4]](http://blogs.conchango.com/blogs/howardvanrooijen/WindowsLiveWriter/UsingLINQDynamicExpressionstoeasePropert_DE5D/clip_image002%5B4%5D_thumb.jpg)
After doing a bit of research it became quite apparent that although incredibly adaptable, the PropertyGrid control is an absolute pain to work with as you have to create lots of glue code (TypeConverters) to make your objects display correctly.
I started wondering if there was a way to create some dynamic anonymous types using LINQ (after a conversation with Rob Blackwell of AWS on how he implemented LSharp with LINQ Expression Trees). After reading a few articles about Code Generation with LINQ and while waiting for the nose bleed to stop, I stumbled across this article from the mighty ScottGu which talks about Dynamic LINQ. After downloading the sample I realised that I had found the solution to my problem – the Dynamic LINQ Library. This allows you to create dynamic properties and attach them to dynamic classes (which are essentially anonymous types) and then instantiate them.
The dictionary contains entries for the following values: InstallerType, WixProductId, WiXProductName. In the code below we iterate the dictionary and create DynamicProperties based on the values in the dictionary, attach them to a dynamic class and then instantiate it.
var dynamicProperties = new List<DynamicProperty>();
// Iterate our dictionary and create dynamic properties that match our values.
foreach (KeyValuePair<string, Pair<string, Type>> pair in this.templateProperties)
{
// i.e. we are creating a new Dynamic Property called "InstallerType"
// which is of type string.
dynamicProperties.Add(new DynamicProperty(pair.Key, pair.Value.Second));
}
// Create a dynamic, anonymous type which contains those properties
this.dynamicType = DynamicExpression.CreateClass(dynamicProperties);
// Create an instance of the anonymous type. W00t!
this.dynamicObject = Activator.CreateInstance(this.dynamicType);
This new dynamicObject can now be attached to the PropertyGrid to give the desired experience:

Fill in the values:

Next we have to pull the values back out of the dynamicObject and put them back into the Dictionary so that it can be passed into the T4 Transformation Engine:
var updatedTemplateProperties = new Dictionary<string, Pair<string, Type>>();
foreach (KeyValuePair<string, Pair<string, Type>> pair in this.templateProperties)
{
string value = (string)this.dynamicType.GetProperty(pair.Key).GetValue(this.propertyGrid.SelectedObject, null);
updatedTemplateProperties.Add(pair.Key, new Pair<string, Type>(value, pair.Value.Second));
}
this.templateProperties = updatedTemplateProperties;
Then we can display the dictionary object to prove we have the updated values:
![clip_image002[10]](http://blogs.conchango.com/blogs/howardvanrooijen/WindowsLiveWriter/UsingLINQDynamicExpressionstoeasePropert_DE5D/clip_image002%5B10%5D_thumb.jpg)
I've uploaded a sample application to my CodePlex project.