T4模板

T4模板作为VS2008的一部分出现,他以<# #> 、<#= #>接近于ASP.NET的语言在模板中插入一段段的动态代码块,可以像asp或者ASP.NET一样简单的更让人贴切,相对于CodeDom就更简洁,但是没有了语言层次的抽象,不具有语言独立性,我们必须为同一个功能的模板在不同的语言上写不同的模板,但是在开发中往往c#模板就足够了,以及更简单化所以得到了更多人的青睐。

T4优势:

1:更加贴切:采用的是类似于ASP、ASP.NET的语言块,是的我们的开发更贴切,采用模板方式更加简洁,快速。

2:可维护性:由于是基于文件,不像codedom编译成为dll方式,我们可以随时修改Template文件、重构。

T4最佳实践

IMHO the two most important concepts when writing complex templates is

  1. Separating the model and the view - This helps keeping the template logic to a minimum (often a cause of maintenance problem). Personally I don't think this requires a framework, it only requires that you do it.

  2. Partial is your friend - I use T4 in general to generate skeleton code from the model. Specific behavior might not be worth the effort to put in the model, better often to allow that behavior come in through the use of partial classes or methods.

Not as important but nice

  1. Make the code searchable - I don't rely on T4 Addons because I find none of them good enough, with the lack of IntelliSense in order to navigate the code I have to make the code searchable. It can be as simple as instead of calling a Column property Name, I call it ColumnName.

  2. Insert "tags" in the output - Makes it easier finding the code that generated that part of the output.

Example separating model/view:

<#
    // Model for Dependency Pooperties
    Model = new []
    {
        new ClassDefinition ("MyDataGrid")
            {
                P ("CultureInfo"            , "CultureInfo"),
                P ("Pen"                    , "CellBorderPen"),
                P ("IEnumerable<object>"    , "Rows"),
                C ("WColumnDefinition"      , "Columns"),
            },
    };
#>
// Include the view
<#@ include file="..\T4\DependencyProperties.ttinclude" #>

The view then iterates over the model and generate the dependency properties.

The behavior of the dependency properties are then implemented as partial methods

partial void Changed_Columns(
        ObservableCollection<WColumnDefinition> oldValue, 
        ObservableCollection<WColumnDefinition> newValue
        )
    {
        HookUpColumns(oldValue, null);
        HookUpColumns(newValue, this);            
    }

Note that putting this specific behavior into the model would significantly complicate the model.

Finally; it takes time even for a competent programmer to write metaprograms competently. It took me several attempts before I arrived at a style which I believe is maintainable but for me it was worth the effort as I am able to ship quality faster.

I hope this helps...

PS. I don't Think anyone would argue T4 is ever elegant but it's darn useful nonetheless.

T4 toolbox

T4 ToolBox是一个CodePlex上开源的工具,它包含一些可以直接使用的代码生成器,比如Enum SQL View、AzMan wrapper、LINQ to SQL classes、LINQ to SQL schema和Entity Framework DAL等。

参见