How to create multiple output files from a single T4 template using Tangible Editor?

 ̄綄美尐妖づ 提交于 2019-12-18 16:52:35

问题


I tried to follow this tutorial: http://t4-editor.tangible-engineering.com/blog/how-to-generate-multiple-output-files-from-a-single-t4-template.html

with visual studio 2015 (.Net 4.5)

Sample project with error: http://www.filedropper.com/t4fail


I created the Template1.tt with the following source:

<#@ include file="TemplateFileManagerV2.1.ttinclude" #>
<#@ Assembly Name="System.Core" #>
<#@ Assembly Name="System.Windows.Forms" #>
<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Diagnostics" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.Collections.Generic" #> 
<#
    var manager = TemplateFileManager.Create(this);
#>

I added TemplateFileManagerV2.1.ttinclude from template gallery to my project.

Then I got an error:

'Microsoft.VisualStudio.TextTemplating.IDebugTextTemplatingEngine' is defined in an assembly that is not referenced. You must add a reference to assembly 'Microsoft.VisualStudio.TextTemplating.Interfaces.11.0, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.

So I added references to

C:\Windows\Microsoft.NET\assembly\GAC_MSIL\Microsoft.VisualStudio.TextTemplating.11.0\v4.0_11.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.TextTemplating.11.0.dll

and

C:\Windows\Microsoft.NET\assembly\GAC_MSIL\Microsoft.VisualStudio.TextTemplating.Interfaces.11.0\v4.0_11.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.TextTemplating.Interfaces.11.0.dll

to my project, but nothing changed.


The error was in the following method inside .ttinclude

public string GetTemplateContent(string templateName, TextTemplatingSession session)
    {
        string fullName = this.Host.ResolvePath(templateName);
        string templateContent = File.ReadAllText(fullName);

        var sessionHost = this.Host as ITextTemplatingSessionHost;
        sessionHost.Session = session;

        Engine engine = new Engine();
        return engine.ProcessTemplate(templateContent, this.Host);
    }

I replaced it with

public string GetTemplateContent(string templateName, TextTemplatingSession session)
    {
        string fullName = this.Host.ResolvePath(templateName);
        string templateContent = File.ReadAllText(fullName);

        var sessionHost = this.Host as ITextTemplatingSessionHost;
        sessionHost.Session = session;

        //Engine engine = new Engine();
        return "";//engine.ProcessTemplate(templateContent, this.Host);
    }

to check if the problem is indeed in dll and got:

'Microsoft.VisualStudio.TextTemplatingA30AC8B57EFC4307E43667FCD72F5E4857F498C5224AE0D43FFC74B3A98D4FA090794EF196648D62B1BC664AFBA5EDE831067D7D1768A759EBBE83426975F7AA.GeneratedTextTransformation' does not contain a definition for 'Host' and no extension method 'Host' accepting a first argument of type 'Microsoft.VisualStudio.TextTemplatingA30AC8B57EFC4307E43667FCD72F5E4857F498C5224AE0D43FFC74B3A98D4FA090794EF196648D62B1BC664AFBA5EDE831067D7D1768A759EBBE83426975F7AA.GeneratedTextTransformation' could be found (are you missing a using directive or an assembly reference?)

It seems, that it's not.


回答1:


I remember I found an easier way to do it back in 2010, but now, after looking across the web for that method, I couldn't find it again. So, after some digging, I managed to find it in an old source code repository. Here's how I did it back then, without making use of any external file or dependency:

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ output extension=".txt" #>
<#
for (Int32 i = 0; i < 10; ++i) {
#>
Content <#= i #>
<#
  // End of file.
  SaveOutput("Content" + i.ToString() + ".txt");
}
#>
<#+
private void SaveOutput(string outputFileName) {
  string templateDirectory = Path.GetDirectoryName(Host.TemplateFile);
  string outputFilePath = Path.Combine(templateDirectory, outputFileName);
  File.WriteAllText(outputFilePath, this.GenerationEnvironment.ToString()); 
  this.GenerationEnvironment.Remove(0, this.GenerationEnvironment.Length);
}
#>

Please note that I don't know who the original author of this method is. If you happen to know who he or she is, please leave a comment.




回答2:


<#@ template hostSpecific="true"#>

on top of .tt file solves everything.




回答3:


This is the documentation from Tangible Engineering:

https://t4-editor.tangible-engineering.com/blog/how-to-generate-multiple-output-files-from-a-single-t4-template.html

It requires you to include and use the Template File Manager. The steps are briefly as follows:

  • Obtain the file manager from their free code gallery (https://t4-editor.tangible-engineering.com/Download_T4Editor_Plus_ModelingTools.html)
  • Include the file manager in the main template file:
    <#@ include file="TemplateFileManagerV2.1.ttinclude" #>
  • Instantiate a manager:
    <# var manager = TemplateFileManager.Create(this); #>
  • Use the manager to start a new file:
    <# manager.StartNewFile("Outputfile2.txt"); #>
    Note that this will end a previously started file before starting the next.
  • Generate template code as normal (will be generated in new file until another file is started or files are processed below)
  • Finalize all files (will end previously started file):
    <# manager.Process(); #>

Also, this method will automatically add the new files to the project.



来源:https://stackoverflow.com/questions/33575419/how-to-create-multiple-output-files-from-a-single-t4-template-using-tangible-edi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!