T4模板和运行时参数

Raf*_*aeu 8 c# t4 template-engine visual-studio-2010

我正在VS 2010中构建一个插件,我陷入了T4代.现在我已经实现了(像MSDN建议的)一个自定义T4主机来生成我的T4结果,我以这种方式使用它:

        const string content = @"c:\Simple.tt";
        var engine = new Engine();
        var host = new MyTemplateHost();            
        var result = engine.ProcessTemplate(File.ReadAllText(content), host);
        foreach (CompilerError error in host.Errors)
        {
            Console.WriteLine(error.ErrorText);
        }
Run Code Online (Sandbox Code Playgroud)

这有效,直到我在模板中传递参数.一旦我在.tt文件中创建了一个参数,主机就会说它不知道如何解决它.我看到你可以使用TemplateSession来做到这一点,但我没弄明白如何将它传递给我的主机?是否有更好的方法使用C#从.tt生成代码并在运行时传递参数?也许我走错了路.

Raf*_*aeu 12

在Visual Studio 2010中,T4模板引擎已经彻底改变.现在,您可以直接运行模板文件并将所需的任何参数类型传递给它.

        var template = Activator.CreateInstance<SimpleTemplate>();
        var session = new TextTemplatingSession();
        session["namespacename"] = "MyNamespace";
        session["classname"] = "MyClass";
        var properties = new List<CustomProperty>
        {
           new CustomProperty{ Name = "FirstProperty", ValueType = typeof(Int32) }
        };
        session["properties"] = properties;
        template.Session = session;
        template.Initialize();
Run Code Online (Sandbox Code Playgroud)

该语句将处理以下模板:

<#@ template language="C#" debug="true"  #>
<#@ output extension=".cs" #>
<#@ assembly name="System.dll" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="SampleDomain.Entities" #>
<#@ parameter name="namespacename" type="System.String" #>
<#@ parameter name="classname" type="System.String" #>
<#@ parameter name="properties" type="System.Collections.Generic.List<CustomProperty>" #>

using System;
using System.Collections.Generic;
using SampleDomain.Entities;

namespace <#= this.namespacename #>
{
public class <#= this.classname #>
Run Code Online (Sandbox Code Playgroud)

老实说,主人不再需要......


Gar*_*thJ 7

如果要为VS构建加载项,则可能不需要自定义主机,而是可以通过其服务接口使用内置VS主机.

查看ITextTemplating作为核心服务API,您可以通过将DTE对象转换为IServiceProvider,然后调用GetService(typeof(STextTemplating))来获取

要传递参数,您可以将ITextTemplating对象播到ITextTemplatingSessionHost,并将Session属性设置为ITextTemplatingSession的实现.会话本质上只是一个可序列化的属性包.有一个简单的提供TextTemplatingSession.


小智 7

向自定义主机添加并实施ITextTemplatingSessionHost.仅实现ITextTemplatingEngineHost不会为您提供会话支持.

 [Serializable()]
    public class CustomCmdLineHost : ITextTemplatingEngineHost,ITextTemplatingSessionHost
    {

        ITextTemplatingSession session = new TextTemplatingSession();

        public ITextTemplatingSession CreateSession()
        {
            return session;
        }

        public ITextTemplatingSession Session
        {
            get
            {
                return session;
            }
            set
            {
                session = value;
            }
        }
Run Code Online (Sandbox Code Playgroud)