Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Conditional compilation symbols be used within T4 templates

I have a T4 template that is used with the TextTemplatingFilePreprocessor to generate a class that I can then use to generate the output of the template.

At the start of the T4 template I import several namespaces. E.g.

<#@ import namespace="Company.ProductX.Widgets" #>
<#@ import namespace="Company.ProductX.Services" #>
//...

I'd like to use Preprocessor Directives to switch out these imports with another set of namespaces (which provide the same interfaces but differing functionality to ProductX). E.g.

<#
#if(ProductX)
{
#>
    <#@ import namespace="Company.ProductX.Widgets" #>
    <#@ import namespace="Company.ProductX.Services" #>
    //...
<#
}
#endif
#>
<#
#if(ProductY)
{
#>
    <#@ import namespace="Company.ProductY.Widgets" #>
    <#@ import namespace="Company.ProductY.Services" #>
    //...
<#
}
#endif
#>

With the above example the imports seem to create the corresponding using statements in the class regardless of the preprocessor directive. E.g.

using Company.ProductX.Widgets
using Company.ProductX.Services
using Company.ProductY.Widgets
using Company.ProductY.Services

Is there another way to use Preprocessors in T4 templates to affect the template itself rather than just the template output?

like image 677
Daniel Ballinger Avatar asked Sep 21 '11 01:09

Daniel Ballinger


People also ask

What is conditional compilation symbols?

Conditional compilation can be useful when compiling code for a debug build or when compiling for a specific configuration. A conditional directive beginning with an #if directive must explicitly be terminated with an #endif directive. #define lets you define a symbol.

What is meant by conditional compilation?

Conditional compilation provides a way of including or omitting selected lines of source code depending on the values of literals specified by the DEFINE directive. In this way, you can create multiple variants of the same program without the need to maintain separate source streams.

What are preprocessor directives C#?

Preprocessor Directives in C# tell the compiler to process the given information before actual compilation of the program starts. It begins with a hashtag symbol (#) and since these preprocessors are not statements so no semi-colon is appended at the end.


1 Answers

In your example the preprocessor directive is injected into the generated output. What you could potentially do is having a ProductX.tt file that imports the correct namespace and uses <#@ include #> to include the template code.

Something like this (ProductX.tt):

<#@ import namespace="Company.ProductX.Widgets"  #>
<#@ import namespace="Company.ProductX.Services" #>

<#@ include file="TheTemplateCode.ttinclude"     #>

(ProductY.tt):

<#@ import namespace="Company.ProductY.Widgets"  #>
<#@ import namespace="Company.ProductY.Services" #>

<#@ include file="TheTemplateCode.ttinclude"     #>

I am not sure if this helps you but to be honest I am struggling a little bit with the use-case here.

like image 89
Just another metaprogrammer Avatar answered Dec 31 '22 18:12

Just another metaprogrammer