Can you use global variables inside a t4 template?

旧时模样 提交于 2019-12-04 11:20:50

I don't think that is possible. When T4 parses your template it is actually generating a class. All the <# #> contents are injected into a single method on that class while all <#+ #> tags are added as methods to that class, allowing you to call them from the single method <# #> tags. So the scope of the "ValueForThisFile" variable is limited to that single method. For a simple example, this template:

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<# 
     int ValueForThisFile = 35;

     SomeFunction();
#>

<#+
void SomeFunction() {
   return ValueForThisFile;
}
#>

Would Generate a class like this:

class T4Gen {

private void MainWork() {
    int ValueForThisFile = 35;
    this.SomeFunction();
}

private void SomeFunction{
    return ValueForThisFile;
}

}

The variable "ValueForThisFile" is only scoped to the MainWork function. The actual class T4 generates is much more complicated but as you see there would be no way to have a global variable in code like that.

Structuring your T4 script like this might help, I have been using similar approaches in my projects successfully: -

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<#     
    var Context = new ScriptContext();
    Context.SomeFunction();
#>
// This file is generated by Build/Info.tt, do not modify!
void SomeFunction() {
    public void GeneratedCode() { 
        int value = <#=Context.ValueForThisFile#>;
    }
}

<#+
public class ScriptContext {
    public int ValueForThisFile = 35;

    public void SomeFunction()
    {
        ValueForThisFile = 42;
    }
}
#>

Its possible to share variable accross functions in T4 template, Try this,

<#@ template  debug="true" hostSpecific="true" #>
<#@ output extension=".cs" #>
<#@ import namespace="System.Collections.Generic" #> 
<#
    InitGlobalVariable();
    AddNames();
    ShowNames();

#>

<#+
    //T4 Shared variables
    List<string> names;
#>

<#+

private void InitGlobalVariable()
{
    names = new List<string>();
}

private void AddNames()
{
    names.Add("Mickey");
    names.Add("Arthur");
}

private void ShowNames()
{
    foreach(var name in names)
    {
#>
        <#= name #>
<#+  
    }
}
#>

Declare your variable inside <#+ ... #> and then initialize inside <# ... #>

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!