2014-10-30 97 views
0

我有一個DSL模型和多個T4模板,可以生成對應於模型的代碼。我想要做的是所有模板都在保存模型後執行。每個模板創建多個輸出文件。我從理論上知道如何爲將處理模板並返回生成的代碼的模型創建自定義工具。但是我怎樣才能處理多個模板,因爲IVsSingleFileGenerator接口返回一個生成的文件。使用自定義工具處理多個T4模板

我想到的一種方法是創建一個「主」T4,使用應該處理的模板中的公共方法。但是之後,我必須在每個模板中寫入數百個「Write()」調用的醜陋方法,因爲在「<#+」內部,不可能像模板的其餘部分那樣編寫純文本。或者我可以創建一個包含要生成的所有文件的代碼的巨大模板。但我覺得這很醜陋,很混亂。

或者有沒有辦法以某種方式實例化T4模板,並讓它自己處理和創建文件?我只知道如何實例化模板,以便它可以被處理,但我只得到生成的代碼,我必須處理自己。

回答

0

因爲我使用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); 
    } 
} 
0

我不知道如何從一個類功能文本(<#+),但它在MSDN的描述:

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)); 
      } 
} 
#>