简体   繁体   中英

How to prevent T4 (.tt) template from being generated upon programmatic condition

I am using Visual Studio 2010 TextTemplatingFileGenerator custom tool to generate C# code (.cs) and would like to know if is there a way of preventing a given .tt from being completely generated upon a given programmatic condition.

I want to achieve the following:

  • Sometimes I want to generate a regular editable class;
  • Other times I want to generate a pair of classes to represent a parent-child relation, each of them implementing their specific set of rules required by their role.

Before answering, please bear in mind that DO NOT intend to use TextTemplatingFilePreprocessor - I already have explored its strengths and weaknesses. Although is suitable for other scenarios, is not for my current context. So I really want to stick to TextTemplatingFileGenerator .

I am not 100% what the scenario is here but it sounds like what you want is to generate code that would allow you to edit parts of the generated code and when regenerating keep your changes. If this is not what you are looking for you can disregard this post (but please offer more explaination of your scenario in that case).

The above scenario is AFAIK not possible in T4. However, if you are generating C# code you can use the partial keyword to achieve that some parts of the code are generated while other parts are hand written.

Let's say you generate class A. The T4 template should then apply the partial attribute to the generated classes.

// This class is auto-generated
partial class A 
{ 
     int X; 
}

This will allow you to extend the generated classes with new members in another file which you maintain by hand.

// This class is manually written
partial class A 
{
    int Y; 
}

The final class A will contain fields X and Y.

You can also change behavior of class A by using partial methods

Hope this helps

If you can live with a minimal stub file being generated for all of A, B, C (or alternatively one 'control' file that always generates a minimal stub) then you can do this directly with T4 using something like Damien Guard's multiple file output technique.

http://damieng.com/blog/2009/11/06/multiple-outputs-from-t4-made-easy-revisited

This can be controlled programmatically from your template.

After a lot of digging, I realized the solution had always been right in the front of my eyes. I just needed a multi-part class which composition is dynamic. Sometimes the result is based on a subset and another times, on another subset.

So, here is goes

<#@ template debug="true" hostSpecific="true" #>
<#@ output extension=".cs" #>
<#

    var IsParent = true; // setting to false prevents Parent code from being generated
    var IsChild = true; // setting to false prevents Child code from being generated

    GenHeader();

    if (IsParent)
        GenParentProperties();

    if (IsChild)
        GenChildProperties();

    GenFooter();

#>

<#+
    void GenHeader()
    {
#>
// Code generated by a template

using System;

namespace StackOverflow
{
    public class Person
    {
        string Name;
        int Age;
<#+
    }
#>


<#+
    void GenParentProperties()
    {
#>
        Person[] Childs;
<#+
    }
#>

<#+
    void GenChildProperties()
    {
#>
        Person Father;
        Person Mother;
<#+
    }
#>

<#+
    void GenFooter()
    {
#>
    }
}
<#+
    }
#>

Hope it helps someone else. Cheers!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM