.nett4

T4 conditionally including templates


I am creating a T4 template that I wish to conditionally include templates based on some criteria. For example I have tried the following...

<#switch(iocContainer) {#>
<#case "Autofac":#>
    <#@ include file="Autofac\EntityTemplate.ttinclude" #>
    <#@ include file="Autofac\ServiceTemplate.ttinclude" #>
    <#@ include file="Autofac\RepositoryTemplate.ttinclude" #>
    <#@ include file="Autofac\DbContextTemplate.ttinclude" #>
<#break;#>

<#case "Castle":#>
    <#@ include file="Castle\EntityTemplate.ttinclude" #>
    <#@ include file="Castle\ServiceTemplate.ttinclude" #>
    <#@ include file="Castle\RepositoryTemplate.ttinclude" #>
    <#@ include file="Castle\DbContextTemplate.ttinclude" #>
<#break;#>

<#case "nInject":#>
    <#@ include file="nInject\EntityTemplate.ttinclude" #>
    <#@ include file="nInject\ServiceTemplate.ttinclude" #>
    <#@ include file="nInject\RepositoryTemplate.ttinclude" #>
    <#@ include file="nInject\DbContextTemplate.ttinclude" #>
<#break;
}#>

The problem is when the templating engine runs, it appears to preprocess all the includes before evaluating any code. So the switch statement above isn't running and T4 attempts to include all the files.

Is there a way to conditionally include T4 templates?


Solution

  • No, T4 doesn't include conditional includes by design. The directives will all be processed.

    If you invert your logic you can solve this. Split the T4 content above and below your switch statement into two separate files (let's call them start.ttinclude and end.ttinclude). Then create three separate T4 templates called, say, autofac.tt, castle.tt and ninject.tt. These would each looks something like this (this is castle.tt):

    <#@ include file="start.ttinclude" #>
    <#@ include file="Castle\EntityTemplate.ttinclude" #>
    <#@ include file="Castle\ServiceTemplate.ttinclude" #>
    <#@ include file="Castle\RepositoryTemplate.ttinclude" #>
    <#@ include file="Castle\DbContextTemplate.ttinclude" #>
    <#@ include file="end.ttinclude" #>