0

我正在尝试编写一个控制台程序,它将 T4 模板的文件名作为参数,然后处理该模板。这是因为我希望用户能够更新模板而无需重新编译程序。

我找到的最简单的解决方案是在 Visual Studio 中创建第二个模板,该模板预编译为 C# 类,然后执行我的外部模板“Template.tt”:

<#@ template language="C#" hostspecific="True" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #>
<#
    string template = File.ReadAllText(Host.ResolvePath("Template.tt"));
    Engine engine = new Engine();
    string output = engine.ProcessTemplate(template, Host);
    Write(output);
#>

在我的控制台程序的 Program.cs 中,我然后执行这个“调用”模板:

string templateText = new Caller().TransformText();

问题是当我运行这个 (F5) 时,它会在调用者模板的第一行抛出 NullReferenceException,因为 Host 为空。

但是,我认为将 hostspecific 设置为 True 会给我一个 Host。

我需要做什么才能获得主机?真的不想自己动手。或者,是否有更好的方法来执行外部 T4 模板?

4

2 回答 2

0

实际的自定义(基于命令行应用程序)T4 主机并不太难实现,我不记得我是从哪里得到代码的,但这里是我们的 T4 模块化控制台应用程序运行器的链接: https://github .com/abstractiondev/absbuilder

实际的命令行主机在这里: https ://github.com/abstractiondev/absbuilder/blob/master/AbstractionBuilder/CustomCmdLineHost.cs

为了引用 T4 部分,我们已经在 Linux 中使用 Mono 运行时/MonoDevelop 环境运行了工具,现在基于测试(那是 1-2 年前),我记得 MonoDevelop 的 T4 完全兼容并可作为源代码使用一些非常明智的许可(如果我没记错的话,是 MIT 或 Apache 2.0)。

于 2013-05-22T16:05:57.317 回答
0

根据MSDN 文档,hostspecific 属性仅提供对 t4 模板内的 Host-Property 的访问。它不保证主机的存在。对于设计时模板(在 Visual Studio 中转换),Visual Studio 和它的 T4 引擎提供了这个宿主。不幸的是,Microsoft.VisualStudio.TextTemplating.dll 不是可再发行程序集。因此,您不会在运行时场景中拥有该主机。

正如您所说,您需要编写一个完整的 T4 引擎并自己托管...

如果您的用户需要编写/更改 t4 模板,他们应该具备编程和编写文本模板的知识。你能想出一种方法让他们以任何方式使用视觉工作室吗?

或者(如果这些用户所做的更改很小),您可以尝试使用适用于其他输入(xml 文件、ini 文件、命令行参数...)的预编译模板。

抱歉没有更好的消息...

于 2013-05-21T19:51:16.210 回答