如何用T4生成一个简单的类?

时间:2017-02-20 20:20:20

标签: c# templates code-generation t4

我正在研究一个VSPackage,它应该从数据库中的某些数据生成简单的类。我已经有了一个静态方法GetFieldInfo,可以从数据库中获取所需的数据,而GetFieldInfo会返回List<TableField>,其中TableField是一个包含所有数据的自定义类我需要。

到目前为止,我的T4模板看起来像这样:

<#@ template language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Threading.Tasks" #>
<#@ output extension=".cs" #>
<#@ parameter name="namespace" type="System.String" #>
<#@ parameter name="className" type="System.String" #>
<#@ parameter name="fields" type="System.Collections.Generic.List<TableField>" #>

namespace <#= this.namespace #>
{
    public class <#= classname #>
    {
        <#
            foreach (TableField campo in fields)
            {

            }
        #>
    }
}

所有这些(静态方法,自定义类和模板)都位于同一项目中的不同命名空间中。这个项目(我们称之为“帮助项目”)不是VSPackage项目(它在VSPackage项目中作为参考添加)。

我的问题是,这个模板会排出27个难以理解的错误(例如{2}第2行Class, delegate, enum, interface or struct expected;第7行第9列} expected;第15行method must have a return value,第18栏,坦率地说,我甚至不知道从哪里开始检查。我的直觉告诉我,当有很多奇怪的错误时,通常是因为几个简单的东西,dev忘记添加/配置,但到目前为止,我还没有找到任何可以帮助我的东西。我在谷歌找不到通过T4生成课程的教程/示例。

我想要生成什么?这样:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace [TARGET_PROJECT_NAMESPACE]
{
    public class [TABLE_NAME]
    {
        public [FIELD_TYPE] [FIELD_NAME] { get; set; }
    }
}

那么,我做错了什么?

2 个答案:

答案 0 :(得分:1)

抱歉,无法添加评论 - 仍然没有“50声誉”。

首先 - 您需要引用名称空间,其中定义了TableField和您在模板中使用的其他部分。添加&lt;#@ import namespace =“your.namnespace”#&gt;。

第二 - 你想在生成的代码中有很多“使用”语句 - 你需要将它们作为文本放入模板中。

关于VSPackage - 请记住,您有两个阶段 - 模板编译和代码生成,并且有两个自定义工具可以执行第一个或两个阶段。在使用包时,很可能需要在开发阶段和模板执行时进行模板编译。

提示:如果模板没有做它想做的事情 - 将模板简化为基本模式 - 让他一次又一次地生成相同的静态代码。

答案 1 :(得分:1)

右键点击.tt文件,确保Custom Tool的值设置为TextTemplatingFilePreProcessor

创建新模板时的样板代码应该为您生成一个类 - 例如,如果您将模板命名为StackOverflowTemplate.tt,那么您也应该有一个名为StackOverflowTemplate的类。

您可以实例化StackOverflowTemplate类,将参数添加到模板中,如下所示:

<强> Program.cs的

public class Program
{
    static void Main(string[] args)
    {
        List<TableField> fields = new List<TableField>();

        StackOverflowTemplate sft = new StackOverflowTemplate();
        sft.Session = new Dictionary<string, object>();
        sft.Session.Add("_namespace", "TargetProjectNamespace");
        sft.Session.Add("className", "ClassName");
        sft.Session.Add("fields", fields);
        sft.Initialize();
        string output = sft.TransformText();
        Console.WriteLine(output);
        Console.ReadKey();
    }
}

<强> StackOverflowTemplate.tt

<#@ template language="C#" #>
<#@ parameter name="_namespace" type="System.String" #>
<#@ parameter name="className" type="System.String" #>
<#@ parameter name="fields" type="System.Collections.Generic.List<TableField>" #>
namespace <#= _namespace #>
{
    public class <#= className #>
    {
        <#
            foreach (TableField campo in fields)
            {

            }
        #>
    }
}