I've got a DSL model and multiple T4 templates that generate code corresponding to the model. What I want to do is that ALL templates are executed upon save of the model. Each template creates multiple output files. I know theoretically how to create a custom tool for the model that will process a template and return the generated code. But how can I process multiple templates, since the IVsSingleFileGenerator interface returns a single generated file.
One way I think about is to create a "master" T4 that uses public methods from the templates that shall be processed. But then I've to write ugly methods in each template with hundreds of "Write()" calls because inside of a "<#+" it's not possible to write plain text like in the rest of the template. Or I could create one huge template that contains the code for ALL files to be generated. But that's ugly and very confusing I think.
Or is there a way to somehow instantiate a T4 template and let it process and create the files on it's own? I know only how to instantiate the template so that it can be processed but I only get the generated code that I've to handle self.
I didn't know how to generate text from a class feature (<#+) but it's described in 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));
}
}
#>