T4:调用写入调用者模板的外部方法

T4: Call external method that writes to the caller template

我正在开发一个基于 T4 的框架,我想知道是否有一种方法可以调用写入调用方模板调用的方法(由 T$ 模板在自定义 dll 引用中定义)。

我知道我可以添加标签: <#= CallMethodThatReturnsString #>

到模板并完成它,但用户往往会忘记“=”符号,所以我想知道是否有一种方法可以使用标准 <# #> 指令调用方法并以编程方式写入该位置。

谢谢

是的,有。

默认情况下,从 T4 模板生成的代码继承自 Microsoft.VisualStudio.TextTemplating.TextTransformation。这个 class 有一个 Write 方法,这意味着这两个指令是等价的:

<#= Guid.NewGuid() #>
<# Write("{0}", Guid.NewGuid()); #>

您需要获得对 this 的引用才能调用 Write。您可以为您的库强制执行一些初始化,例如:

<# MyLib.Initialize(this); #>

然后将其存储在 static ThreadLocal<TextTransformation> 字段中。

但我发现这种方法存在一些问题:

  • 如果你的库的用户忘记调用 Ìnitialize
  • 显然是行不通的
  • 如果您的库的用户想要使用 继承自 TextTransformation 的自定义模板基础 class,它将无法工作。您必须使用 dynamic 来规避
  • 现在,不再需要 =,但您只是在最后将其换成了强制性的 ; ;)

话虽如此,我不建议您这样做 - 只是不要打扰并继续要求标准 <#= #>

... 或者,如果可行,您可以为模板编写自己的自定义基础 class 并在其中实现您的库。只需扩展 TextTransformation 并使用 <#@ template language="C#" inherits="MyLib" #>