Thursday, June 23, 2011

The GAX Property Directive

One of the things that really bother me about T4 templates is the lack of direct parameter support (at least in the Visual Studio 2008/.NET 3 timeframe).

In an earlier post, I passed parameter by writing the parameter data to a file outside of the template and reading the data from within. I used a common assembly linked to both sides of the divide. This works for me, but it is really hacky.

GAX Template Host

During my preparation for my Portland Code Camp presentation, I came across Guidance Automation Toolkit for Visual Studio 2008. It has its own TemplateHost that includes a Dictionary of parameters.

Parameters are exposed to the Template through a custom directive. On the template, the parameter is declared using a directive like this:

<#@ property processor="PropertyProcessor" name="MyName" type="String" #>
The directive contains the following parts:
processor Should be "PropertyProcessor" (there may be a way to write your own processor, I haven’t gone down that rat hole yet).
name The Variable name that can appear in your code. It works just like a variable, however, tangable T4 Editor doesn’t provide Intenesence (I wouldn’t have expected it).
type Any .NET Type that the template knows about. You should use the .NET type name (as opposed to C# or VB.NET type).
In C# the parameters are created like this:
var arguments = new Dictionary();
arguments.Add("MyProperty", new PropertyData("String", typeof(string)));
To pass parameters from your code you need to create a Dictionary<string, PropertyData>, add your parameters and pass them as the second argument into the TemplateHost constructor (the first can be any string as far as I can tell).

Simple Sample

The Template

<#@ template language="C#" debug="True" #>
<#@ output extension="txt" #>
<#@ assembly name="System.dll" #>
<#@ import namespace="System" #>
<#@ property processor="PropertyProcessor" name="MyProperty" type="Nullable<Int32>"#>
<#@ property processor="PropertyProcessor" name="MyName" type="String"#>
My Property Test
<# if (MyProperty.HasValue) {#>
Property Value: <#= MyProperty.Value #>!
<#}#>
Name: <#= MyName #>

C# code

static void Main(string[] args)
{
    // Prepare template parameters
    var arguments = new Dictionary<string, PropertyData>();
    arguments.Add("MyProperty", new PropertyData(42, typeof(int?)));
    arguments.Add("MyName", new PropertyData("Jack Stephens", typeof(string)));

    // Initialize GAX template host
    // The Template Host is from GAX, not the default host
    var host = new TemplateHost("Random String", arguments);
    host.TemplateFile = Path.Combine(Directory.GetCurrentDirectory(), 
        "PropertyTest.tt");

    // Transform template
    string template = File.ReadAllText(host.TemplateFile);

    ITextTemplatingEngine engine = new Engine();
    string output = engine.ProcessTemplate(template, host);

    Console.Write(output);
    Console.ReadKey();
}

References

Monday, June 13, 2011

Portland Code Camp 2011 Presentation Notes

Again, I'm late getting this up. I will give usual excuses of being busy. In the future I will not promise anything before the next weekend after the code camp.

Since I developed this talk on this blog, this entry will essentially be a link list. I put a copy of the slides in Google doc and you can reference it here

This presentation is similar, but not the same as a presentation I gave at the Boise Code Camp in February. In the interest of being DRY (Don’t Repeat Yourself) I will reference the notes for that presentation.

Tools

For this presentation, I used the Tangible T4 Editory and the T4 Toolbox.

Template Parts

I presented a slide that showed the basic template parts in a small mock template:

<#@ template language="C#" #>
<#@ directive property=“value” #>
<# var item = "Statement Block"; #>
Text Block 
<#= "Expression Block" #>
<#+ 
    string ClassFeatureBlock(string thingy)
    {
        return thingy;
    } 
#>

Hello World Monty

I showed some of the elementary features of T4 templates by refactoring a basic template that would create a text file that contained the infamous words “Hello World”. A script of that exercise is here

Basic Code Generation Demonstration

To demonstrate Code Generation I set out to generate a simple T-SQL Select Statement using Sql Management Objects (SMO).

Here I will refer to the Boise Code Camp Notes.

Generating Multiple Files using T4 Toolbox

I used the result of the Basic Code Generation Demonstration to attempt to generate select scripts for all the tables in a given database. This demonstration was based on a series of blog posts by Oleg Synch (Part 1, Part 2, Part 3 & Part 4).

I do intend to give my take on this process. Perhaps that is why I'm over a week late on these notes. I will add a link to these notes later.

GAX Property Directive

I discussed using Guidance Automation Extensions's property directive to overcome T4's lack of native support for passing parameters into templates. This part was based on another Oleg Synch article Understanding T4: <#@ property #> directive.

Again, I will add links to future blogs post(s) on this subject here.

Generating a Nullable ADO.NET DataSet Wrapper

This is when I went to Show and Tell Mode. I demonstrate a Nullable DataSet Wrapper that I wrote in these blog entries. I wrote the templates in VB.NET to generate code in C#.

Part 1, Part 2, Part 3 & Part 4

Last Word

This presentation reached too far and, like Icarus, I failed to hit the mark. The number of forward links is a sign of that. I intend to back-blog in the areas the missing material and add links when I am done.