如何解决将对象传递到T4模板
| 我有一个对象类型为“ 1”的对象“ 0”。用户具有属性“ 2”。如何将“ 0”传递给T4模板?我正在尝试做一些非常简单的事情:User u1 = new User(\"John\");
模板脚本:
Hello <# u1.Name #>
解决方法
您想在模板中使用它吗?然后,您需要添加对包含该类型的程序集的引用。您不能简单地将现有引用传递给T4引擎,除非您以某种非常非传统的方式自己托管它(我从未见过有人尝试这样做)。即使您走了那么远,您将如何运行它?这个参考应该从哪里来?
在T4模板中使用类型很容易,只需添加引用或将其复制/粘贴到类存根
<#+ /*stuff goes here*/ #>
中即可。
, 我们做了类似的事情。我们的解决方案具有以下要素:
自定义主机
自定义模板基类(template指令的\“ inherits \”属性)
主机特定的模板(template指令的\“ hostspecific \”属性)
定制主机由模板本身要在其上调用方法的对象聚合。
interface ICallbackInterface
{
void CallbackFxn();
}
[Serializable]
public class MyCustomHost : ITextTemplatingEngineHost,ITextTemplatingSessionHost,IStencilFileRecordManagement
{
private ICallbackInterface callback = null;
public MyCustomHost(ICallbackInterface cb)
{
callback = cb;
}
public void CallbackFxn()
{
callback.CallbackFxn();
}
}
public abstract class MyTemplateBase : TextTransformation
{
public virtual MyCustomHost CustomHost
{
get
{
dynamic metame = this;
MyCustomHost rval = null;
try
{
/// <summary>
/// The \"Host\" property will be added to the generated class by the T4 environment whenever a
/// \"hostspecific\" template is processed.
/// </summary>
rval = metame.Host as MyCustomHost;
}
catch (RuntimeBinderException e)
{
logger.ErrorException(
\"Received the following exception while processing a stencil template\",e);
}
return rval;
}
}
}
现在,在我们的任何模板中,我们可以使用自定义宿主属性在实际上启动处理的对象上调用方法,例如:
<# CustomHost.CallbackFxn(); #>
另外,我们不在VS中使用T4或使用单独的可执行文件-我们链接到Microsoft.VisualStudio.TextTemplating.10.0和Microsoft.VisualStudio.TextTemplating.Interfaces.10.0程序集。
编辑
我们正在使用T4模板,允许用户定义自己的插件,以在我们产品工作流程的特定步骤中使用。因此,用户模板已上传到我们的系统,并按以下方式进行处理:
using Microsoft.VisualStudio.TextTemplating;
class UserPluginWorkflowComponent : ICallbackInterface
{
public void CallbackFxn()
{
// invoked by user plugin
}
public void ExecuteUserPlugin()
{
MyCustomHost host = new MyCustomHost(this);
host.TemplateFileValue = \"UserPluginTemplateFilename\";
Engine engine = new Engine();
string pluginResult = engine.ProcessTemplate(
userPluginTemplateFileContents,host);
if (!host.Errors.HasErrors)
{
// use pluginResult in some meaningful way
}
}
}
, T4模板的处理过程第一步,因此模板需要在运行时获得所需的一切,因为您实际上并没有将任何内容“传递”到模板中。由于模板是文本,因此我通常只需要一些参数,开发人员便可以在文件顶部设置这些参数。如果您需要用户输入,可以弹出一个窗口,但是生成代码时听起来很烦人。
另一个解决方案是使用自定义模板,该模板在t4模板中使用模板替换,类似于许多已安装模板的工作方式。
, 假设您想在某个最终运行模板的应用程序或工具中拥有代码,然后使用运行时(预处理的)模板以及在<#+#>类功能块中定义的自定义属性或<#@ parameter#>指令应提供你想要的。
在这里看看文档:http://msdn.microsoft.com/en-us/library/gg586944.aspx
, 嘿-您需要在T4脚本中设置值等,因此User
初始化必须在<# #>
标记内进行,这会将您的示例转换为类似于
<# User u1 = new User() { .Name = \"John\" } #>
Hello <# u1.Name #>
如上所述,您可能还需要导入名称空间。我已经在TT文件的开头使用以下语句来访问System.Data:
<#@ import namespace=\"System.Data\" #>
<#@ import namespace=\"System.Data.SqlClient\" #>
<#@ assembly name=\"System.Data\" #>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。