Как создать несколько выходных файлов из одного шаблона T4 с помощью Tangible Editor?

Я пытался следовать этому руководству: http://t4-editor.tangible-engineering.com/blog/how-to-generate-multiple-output-files-from-a-single-t4-template.html

с визуальной студией 2015 (.Net 4.5)

Пример проекта с ошибкой: http://www.filedropper.com/t4fail


Я создал Template1.tt со следующим источником:

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

я добавил TemplateFileManagerV2.1.ttinclude из галереи шаблонов в мой проект.

Тогда я получил ошибку:

"Microsoft.VisualStudio.TextTemplating.IDebugTextTemplatingEngine" определяется в сборке, на которую нет ссылок. Необходимо добавить ссылку на сборку "Microsoft.VisualStudio.TextTemplating.Interfaces.11.0, версия = 11.0.0.0, культура = нейтральная, PublicKeyToken=b03f5f7f11d50a3a".

Поэтому я добавил ссылки на

C:\Windows\Microsoft.NET\ сборка \GAC_MSIL\Microsoft.VisualStudio.TextTemplating.11.0\v4.0_11.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.TextTemplating.11.0.dll

а также

C:\Windows\Microsoft.NET\ сборка \GAC_MSIL\Microsoft.VisualStudio.TextTemplating.Interfaces.11.0\v4.0_11.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.TextTemplating.Interfaces.11.0.dll

в мой проект, но ничего не изменилось.


Ошибка была в следующем методе внутри .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);
    }

Я заменил его

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

проверить, действительно ли проблема в DLL и получил:

"Microsoft.VisualStudio.TextTemplatingA30AC8B57EFC4307E43667FCD72F5E4857F498C5224AE0D43FFC74B3A98D4FA090794EF196648D62B1BC664AFBA5EDE831067D7D1768A759EBBE83426975F7AA.GeneratedTextTransformation" не содержит определение для "хозяина", а метод расширения "Host" принимающего первый аргумент типа "Microsoft.VisualStudio.TextTemplatingA30AC8B57EFC4307E43667FCD72F5E4857F498C5224AE0D43FFC74B3A98D4FA090794EF196648D62B1BC664AFBA5EDE831067D7D1768A759EBBE83426975F7AA.GeneratedTextTransformation" может быть найдено (вы пропали без вести с помощью директивы или ссылка на сборку?)

Кажется, что это не так.

2 ответа

Решение

<#@ template hostSpecific="true"#>

на вершине .tt файл решает все

Я помню, я нашел более простой способ сделать это еще в 2010 году, но теперь, после поиска в Интернете этого метода, я не смог найти его снова. Итак, после некоторых копаний мне удалось найти его в старом хранилище исходного кода. Вот как я это сделал тогда, не используя никаких внешних файлов или зависимостей:

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

Обратите внимание, что я не знаю, кто является первым автором этого метода. Если вы знаете, кто он, пожалуйста, оставьте комментарий.

Это документация Tangible Engineering:

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

Требуется включить и использовать диспетчер файлов шаблонов. Кратко о следующих шагах:

  • Получите файловый менеджер из их бесплатной галереи кода ( https://t4-editor.tangible-engineering.com/Download_T4Editor_Plus_ModelingTools.html)
  • Включите файловый менеджер в основной файл шаблона:
    <#@ include file="TemplateFileManagerV2.1.ttinclude" #>
  • Создайте менеджера:
    <# var manager = TemplateFileManager.Create(this); #>
  • Используйте менеджер, чтобы начать новый файл:
    <# manager.StartNewFile("Outputfile2.txt"); #>
    Обратите внимание, что это завершит ранее запущенный файл перед началом следующего.
  • Генерация кода шаблона как обычно (будет создаваться в новом файле до тех пор, пока другой файл не будет запущен или файлы не будут обработаны ниже)
  • Завершить все файлы (закончится ранее запущенный файл):
    <# manager.Process(); #>

Также этот метод автоматически добавит новые файлы в проект.

Другие вопросы по тегам