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" #>
我正在开发一个基于 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" #>