Home MVC Storefront

Make Visual Studio Generate Your Repository

As many of you may know, I've been goofing around with Code Generation again with SubSonic's new MVC Addin. One of the things I really wanted to try and flex is Visual Studio 2008's code generation bits - T4. Not many people know it even exists, and to me it's one of the Great Hidden Secrets of Visual Studio 2008.

What Is T4?
Quite literally, T4 stands for

Text Template Transformation Toolkit

Otherwise known as Code Generation. MSDN has a nice writeup on T4 as well. The easiest way to think of T4 is that it's just like coding ASP - except the script that you create is code that stays inside Visual Studio.

Every T4 script file (extension TT) is "executed" whenever a save happens inside Visual Studio, and the T4 file has been altered - sort of like a Build Provider. The nice thing here, however, is that there is some pretty nice debugging that you can do - and you can even step through the code that Visual Studio is generating.

It's insanely easy to work with T4 and there is a lot of information out there on the web. David Hayden put together (as usual) one of his stellar screencasts, which you can watch here. In addition, Oleg Sych is a T4 Ninja and has just about any resource and/or information you might need on his site.

A Look At The Template Code
Let's jump into the code! One of the things that you may want to do with T4 right off the bat is have it create your DB access code. David Hayden has a nice screencast for how he does it - I thought it would be fun to show you how you can wrap Linq To Sql into a nice, testable framework for use with something like... oh perhaps ASP.NET MVC :).

For these examples I'm going to use the "plumbing" code that I've worked up with SubSonic.Mvc (also known as Makai). I have some bits in there that grab a DBML file and tell me all kinds of nice schema information - I'll use this information to create my template.

First, this is your basic T4 template:

<#@ template language="C#" debug="True" hostspecific="True" #>
<#@ assembly name="System.Data" #>
<#@ assembly name="SubSonic.Mvc.dll" #>
<#@ assembly name="SubSonic.dll" #>
<#@ import namespace="System.Diagnostics" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Data" #>
<#@ import namespace="SubSonic" #>
<#@ import namespace="SubSonic.Mvc" #>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;


namespace Test{   
    
    class Program{
        
        static void Main(string[] args){
            <#for(int i=0;i<10;i++){#>
            Console.WriteLine("<#=i.ToString()#>");
            <#}#>
        }
    } 
   
}

The markup above with the "#" sign is a T4 command. The first few lines load up some assemblies and reference some namespaces. The rest of the code after that is "static" - stuff that will get "rendered" so to speak. If you look inside the Main() method - you can see I'm running a for-loop that outputs the value of the loop index.

The output of this code is:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Test{   
    
    class Program{
        
        static void Main(string[] args){
            Console.WriteLine("0");
            Console.WriteLine("1");
            Console.WriteLine("2");
            Console.WriteLine("3");
            Console.WriteLine("4");
            Console.WriteLine("5");
            Console.WriteLine("6");
            Console.WriteLine("7");
            Console.WriteLine("8");
            Console.WriteLine("9");
        }
    } 
   
}

This is, of course, a very silly example. But hopefully you can see the potential here - and the point of it all :). It's very easy to extend and can be used in any type of project. In addition you can change the output extension to render ... well any type of output you like - HTML, vb, cs, etc.

Whenever you create a T4 template, a "shadow" file is created with it that contains your generated code:

t4

You can use T4 to get yourself started (and then jettison the template), or you can keep your template and modify as you need for your project. Personally I like to use code generation to get me to 80% or so - after that I end up tweaking the template more than my project :).

Wrapping Linq
As I mention above, I've created some templates here that wrap up Linq To Sql in a nice IQueryable Repository (what I've been doing with the storefront). I like the way these templates work - and it makes the repository system nice and simple to use for your project.

The use these, you need to do 3 things:

1) Pop SubSonic.Mvc somewhere on your drive - it doesn't need to be added as a reference to your application - but the templates will need to know where to find it.

2) Change the initial variables of the template to match your project. Each template has the following bits of info that it needs at the top of the template:

    //the path to your Linq To Sql DBML File
    string DBMLFilePath=@"C:\Projects\NorthwindDB.dbml";  
    //the Type name of your DataContext
    string dataContext="NorthwindDB.DB";
    //the namespace of your Linq To Sql Model classes
    string dataNamespace="NorthwindDB.Data";
    //if you've put your DataContext in a different namespace
    //set this to "using [DataContextNamespace]"
    string contextNamespaceDeclaration="";

The neat thing about these templates is you can jigger whatever you need to - you're not going to violate any rules here. This is just a text templating tool - so hard-code away! I've just set these here for clarity :).

3) Tweak as you need to. You will most likely have to tweak the template to get it to compile - that's just the nature of these things :). It uses your Linq To Sql DBML file for its schema reference, so if you want to change naming or whatnot - you should do it there.

Editing Your Own Templates
There's so much you can do with this stuff, it's really amazing. You owe it to yourself to spend a little time and see just how much time you can save by doing some light code-generation (caveat: as with all good things, there is a point of self-destruction brought on by over-indulgence).

One handy tool is Clarius's T4 template editor that brings all the syntax coloring and intellisense to life that you need.

Another nice read is what Damien Guard has done with the Linq To Sql templates that are generated by the designer. Damien works on the Linq To Sql team and has made some great changes to the code generation bits.

P.S. - Yes I will be working some of these up for SubSonic :)

You can grab my templates here.

blog comments powered by Disqus
Search Me
Subscribe

Index Of MVC Screencasts

You can watch all of the MVC Screencasts up at ASP.NET, and even leave comments if you like.

Popular Posts
 
My Tweets
  • @haacked must.... resist... assimilation...
  • Dinner at the Haacks. How did Phil get such a cute kid? Evidently Phil's in the doghouse though...
  • @shanselman dude turn off twitter and drive! that's gotta be illegal!
  • For D'Arcy and Justice... Scottgu goes Canuck! http://twitpic.com/mfz1
  • Working in ScottGu's office with @shanselman. Wearing an Orange Polo and saying "go ahead" a lot for some reason.
  About Me



Hi! My name is Rob Conery and I work at Microsoft. I am the Creator of SubSonic and was the Chief Architect of the Commerce Starter Kit (a free, Open Source eCommerce platform for .NET)

I live in Kauai, HI with my family, and when my clients aren't looking, I sometimes write things on my blog (giving away secrets of incalculable value).