在每次构建期间使用不同参数从模板生成代码

时间:2013-12-04 20:07:47

标签: c# code-generation t4 template-engine

我在C#中编写了一个有点复杂的库,我需要从模板中自动生成大量的样板代码。具体来说,我希望实现以下内容:

public partial class $ClassName$<T>
{
    /// ...
    /// ...
    /// ...
    /// (long documentation)
    public $ClassName$<TOut> Select(Func<T, TOut> selector, $OtherType$<TOut> other = null)
    {
        return base.Select(new $ClassName$<TOut>(other), selector);
    }
}

(您可能会注意到这实际上是试图模仿更高级别的类型参数,但这对问题并不是特别重要。)

但是,我不希望代码以“静态”方式生成,就像“New Item”向导在Visual Studio中生成它一样。这是因为模板本身实际上是“代码”,它可能会发生变化。每当我更改模板时,我都无法使用此样板代码手动重新生成所有类。

这就是为什么我正在寻找一种方法来在每次构建期间生成此代码,或者可能在某些其他操作上生成此代码。由于多个类将使用此样板代码(具有不同的模板参数),因此应为使用它的每个类自动生成代码。将代码提供给IntelliSense也很重要。

我也在寻找一种编写这些模板的工具,并且可能以某种方式管理它们。

任何帮助?

编辑:T4文字模板似乎正是我正在寻找的。但是,如何创建模板的“多个实例”,每个实例具有不同的参数,并将每个实例与不同的类相关联?内置功能似乎只生成一个文件。

3 个答案:

答案 0 :(得分:1)

您可以在Visual Studio中理论上使用T4 templating生成此类代码,并为每个$ClassName$分配模板。

答案 1 :(得分:1)

您是否考虑过使用T4 Text Templates

答案 2 :(得分:1)

您可以按照以下方式进行操作。

0.1。参数化T4

在生成中添加参数化 - 使用传统的类变量或更长的块模板。它在处理过程中根据某些参数值等读取的文件。

0.2。无论是预编译还是即时运行,都可以控制生成

我将复制粘贴部分我接近代码生成的外部控件

    public Tuple<string, string>[] GetGeneratorContent(params string[] xmlFileNames)
{
    List<Tuple<string, string>> result = new List<Tuple<string, string>>();
    foreach(string xmlFileName in xmlFileNames)
    {
        TheBallCoreAbstractionType abs = LoadXml<TheBallCoreAbstractionType>(xmlFileName);
        CurrentAbstraction = abs;
        this.GenerationEnvironment.Clear();
        string content = TransformText();
        string outputFile = Path.GetFileNameWithoutExtension(xmlFileName) + ".designer.cs";
        result.Add(Tuple.Create(outputFile, content));
    }
    return result.ToArray();
}

上面值得注意的事情是TransformText(),它“正常”运行模板,之前是“this.GenerationEnvironment.Clear()”。围绕一些类变量设置然后输出作为文件名+内容返回 - 当然可以只是File.WriteAllText(名称,内容);。

为了进一步的兴趣 - “大规模参数化”我在下面添加了更多...

免责声明我在全面开放模块化T4自动化方面做了大量工作。我将链接几个链接,因为虽然上面的答案有点紧密,T4控制的各种方式(特别是在原始问题的参数化管理的情况下)是非常有趣和非常强大的艺术。

话虽如此 - 这里有一些使用VS2010和T4工具箱的全功能链接,但是可以通过单击“转换所有模板”在后面的工作室中运行没有T4工具箱: https://github.com/kallex/MSTechDays2012Demos

T4演示是从头开始的,ADM部分用于通过T4实现抽象控制。

这种方法很久以前得到了认可,并得到了T4团队的积极反馈:-): http://blogs.msdn.com/b/t4/archive/2011/11/30/some-nice-new-getting-started-with-t4-videos.aspx

从演示视频中可以看到有关可以实现的内容的各种演示,但对于纯/高级T4,我建议使用入门和演示视频。高级T4: http://www.youtube.com/playlist?list=PL6D51E9F1B9C955BB