执行T4模板:主机为空,而hostspecific =“True”

时间:2013-05-21 15:32:05

标签: t4 nullreferenceexception host

我正在尝试编写一个控制台程序,它将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为null。

但是,我认为将hosts特定设置为True会给我一个主机。

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

2 个答案:

答案 0 :(得分:0)

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

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

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

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

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

答案 1 :(得分: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是完全兼容的并且作为源提供代码有一些非常合理的许可(麻省理工学院或Apache 2.0,如果我没记错的话)。