【问题标题】:How to prevent T4 (.tt) template from being generated upon programmatic condition如何防止在编程条件下生成 T4 (.tt) 模板
【发布时间】:2012-08-07 19:42:56
【问题描述】:

我正在使用 Visual Studio 2010 TextTemplatingFileGenerator 自定义工具来生成 C# 代码 (.cs),并想知道是否有办法阻止给定的 .tt 在给定的情况下完全生成程序化条件。

我想实现以下目标:

  • 有时我想生成一个常规的可编辑类;
  • 有时我想生成一对类来表示父子关系,每个类都实现其角色所需的特定规则集。

在回答之前,请记住 不要打算使用 TextTemplatingFilePreprocessor - 我已经探索了它的优点和缺点。虽然适用于其他场景,但不适合我目前的情况。所以我真的很想坚持TextTemplatingFileGenerator。

【问题讨论】:

  • 您是想说要根据 .tt 生成的文件或某些参数生成不同的代码吗?
  • 给定 3 个类(A、B 和 C)。场景 1 应该只生成 A,场景 2 应该只生成 B 和 C。
  • 你如何决定哪个模板生成哪些类?
  • 我根据 XML 设置文件来决定我的模板生成
  • 如果你深入了解T4工具箱是如何处理Linq2SQL codegen的,你会发现很容易根据一些条件调用不同的TT文件,如果生成的内容不改变,文件不会被修改。

标签: c# templates code-generation conditional t4


【解决方案1】:

如果您可以接受为所有 A、B、C 生成的最小存根文件(或者一个始终生成最小存根的“控制”文件),那么您可以使用 Damien Guard 之类的工具直接使用 T4 执行此操作多文件输出技术。

http://damieng.com/blog/2009/11/06/multiple-outputs-from-t4-made-easy-revisited

这可以通过您的模板以编程方式控制。

【讨论】:

  • 是的!我刚刚检查了 Damien Gard 的代码。他的经理课似乎正是我想要的。 Gareth,非常感谢你在这个问题上帮助我,并分享了我已经找到的关于你的其他 sage cmets。干得好!
【解决方案2】:

我不是 100% 的情况是这里的情况,但听起来你想要生成的代码允许你编辑部分生成的代码,并在重新生成时保留你的更改。如果这不是您正在寻找的内容,您可以忽略这篇文章(但请提供更多关于这种情况下您的场景的解释)。

上述情况在 T4 中是不可能的。但是,如果您正在生成 C# 代码,则可以使用 partial 关键字来实现代码的某些部分是生成的,而其他部分是手写的。

假设您生成类 A。然后 T4 模板应将部分属性应用于生成的类。

// This class is auto-generated
partial class A 
{ 
     int X; 
}

这将允许您在您手动维护的另一个文件中使用新成员扩展生成的类。

// This class is manually written
partial class A 
{
    int Y; 
}

最终的 A 类将包含字段 X 和 Y。

您还可以使用部分方法更改 A 类的行为

希望对你有帮助

【讨论】:

  • 嗨,FuleSnabel!我真的很感谢你的cmets。我知道部分类的使用,尽管我已经在粘贴中成功地使用了它,以及 TextTemplatingFilePreprocessor,但我现在真正想要实现的最好是在上面对 PeterLacomb Jr. 评论的评论中总结。还是谢谢!
  • 仅供参考,部分使用 TextTemplatingFileGenerator 与使用 TextTemplatingFilePreProcessor 一样有用
  • 在对 Damien Gard 的方法(见下文)进行了一番思考之后,我意识到为什么你是对的。感谢您指出。
【解决方案3】:

经过大量挖掘,我意识到解决方案一直就在我的眼前。我只需要一个多部分的类,它的组合是动态的。有时结果基于一个子集,有时基于另一个子集。

那么,就这样吧

<#@ template debug="true" hostSpecific="true" #>
<#@ output extension=".cs" #>
<#

    var IsParent = true; // setting to false prevents Parent code from being generated
    var IsChild = true; // setting to false prevents Child code from being generated

    GenHeader();

    if (IsParent)
        GenParentProperties();

    if (IsChild)
        GenChildProperties();

    GenFooter();

#>

<#+
    void GenHeader()
    {
#>
// Code generated by a template

using System;

namespace StackOverflow
{
    public class Person
    {
        string Name;
        int Age;
<#+
    }
#>


<#+
    void GenParentProperties()
    {
#>
        Person[] Childs;
<#+
    }
#>

<#+
    void GenChildProperties()
    {
#>
        Person Father;
        Person Mother;
<#+
    }
#>

<#+
    void GenFooter()
    {
#>
    }
}
<#+
    }
#>

希望它可以帮助别人。干杯!

【讨论】:

    猜你喜欢
    • 2019-06-16
    • 2011-05-10
    • 1970-01-01
    • 2011-05-06
    • 2014-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-16
    相关资源
    最近更新 更多