【问题标题】:Process multiple T4 templates with custom tool使用自定义工具处理多个 T4 模板
【发布时间】:2014-12-26 14:58:27
【问题描述】:
我有一个 DSL 模型和多个生成与模型对应的代码的 T4 模板。我想要做的是在保存模型时执行所有模板。每个模板创建多个输出文件。从理论上讲,我知道如何为模型创建一个自定义工具来处理模板并返回生成的代码。但是如何处理多个模板,因为 IVsSingleFileGenerator 接口返回单个生成的文件。
我想到的一种方法是创建一个“主”T4,它使用来自要处理的模板的公共方法。但是我必须在每个模板中编写丑陋的方法,其中包含数百个“Write()”调用,因为在“
或者有没有办法以某种方式实例化 T4 模板并让它自己处理和创建文件?我只知道如何实例化模板以便处理它,但我只得到我必须自己处理的生成代码。
【问题讨论】:
标签:
c#
visual-studio
code-generation
t4
texttemplate
【解决方案1】:
我不知道如何从类特征 (
Generate text from a class feature
<#+
private void CreateAccessor(ModelClass classType, ModelClass associatedClass, string fromRoleName, string toRoleName)
{
if(!string.IsNullOrEmpty(toRoleName) && !string.IsNullOrEmpty(fromRoleName))
{
string validClassName = MakeValidName(associatedClass.Name);
string validFromName = MakeValidName(fromRoleName);
string validToName = MakeValidName(toRoleName);
#>
private <#= validClassName#> <#= validFromName#>Value;
public <#= validClassName#> <#= validFromName#>
{
get{ return <#= validFromName #>Value; }
set
{
if (<#= validFromName#> != value)
{
if (<#= validFromName#> != null)
<#= validFromName#>.<#=validToName#> = null;
<#= validFromName#>Value = value;
if (value != null)
{
<#= validFromName#>Value.<#=validToName#>=this;
}
}
}
}
<#+
}
else
{
Warning(String.Format("Ignoring BidirectionalAssociation from {0} to {1} because its SourceRoleName or TargetRoleName is not defined", classType.Name, associatedClass.Name));
}
}
#>
【解决方案2】:
因为我使用的是MultipleOutputHelper,所以我可以控制所创建的文件。这使得在代码生成器中处理多个模板变得非常容易:
public class MyCodeGenerator : TemplatedCodeGenerator
{
protected override byte[] GenerateCode(string inputFileName, string inputFileContent)
{
ProcessTemplate(inputFileName, CodeGenerationResource.TemplateX);
ProcessTemplate(inputFileName, CodeGenerationResource.TemplateY);
// since we're using the MultipleOutputHelper class in the t4 templates, which generates the required files on its own, we don't have to return any bytes
return new byte[0];
}
private void ProcessTemplate(string inputFileName, string templateContent)
{
var fi = new FileInfo(inputFileName);
templateContent = templateContent.Replace("Sample.mmd", fi.Name);
base.GenerateCode(inputFileName, templateContent);
}
}