如何禁用写入T4生成输出文件的#line指令

时间:2011-10-25 09:12:29

标签: c# path c-preprocessor t4

我的T4代码生成遇到了一个小问题。

我已经将我的T4模板分解成单独的文件并将它们放在各种目录中,我已经这样做了,因此我的代码生成的一部分可以在多个项目中重复使用,例如模型生成,存储库生成和服务生成都包含一个核心EntityGeneration.tt文件。

不幸的是,当TextTemplating解析我的嵌套包含时,它会在其生成的.cs文件中构建一个长的#line预处理器指令,将所有相对路径组合到最低级别的包含文件。

不幸的是,由于此路径是使用相对路径构建的,因此它会不必要地长,最终会超出最大路径长度(Windows 7)。

如果您感兴趣,以下是生成代码的错误行:

#line 3 "C:\VS2010\AlbatrossTravelGroup\ASC\AlbatrossTravelGroup.ASC.BusinessRules\Services\Contracts\..\..\..\..\AlbatrossTravelGroup.BusinessRules\Services\Contracts\..\..\..\AlbatrossTravelGroup.Models\Repositories\Contracts\..\..\../AlbatrossTravelGroup.Common/CodeGeneration.tt"

我的问题是,如何禁用这些指令写入生成的代码文件?如果不这样做,如何在不更改文件结构的情况下避免此问题?

2 个答案:

答案 0 :(得分:12)

Visual Studio 2012添加了linePragmas="false"模板指令:

<#@ template language="C#" linePragmas="false" #>

http://msdn.microsoft.com/en-us/library/gg586945(v=vs.110).aspx

仍然不确定如何在VS2010中这样做,我在工作中坚持。

答案 1 :(得分:0)

我不确定这会解决您的问题。我对T4没有太多经验。也就是说,我正在使用它在我的项目中构建了许多文件,而且我没有遇到你遇到的问题。

就我而言,我有一堆单独的.tt文件,可以在我的项目中呈现单个文件。

我这样做的方式如下:我有一个SaveOutput方法(我相信在stackoverflow上的某个地方被盗):

void SaveOutput(string outputFileName)
{
    if (!string.IsNullOrEmpty(outputFileName))
    {
        string templateDirectory = Path.GetDirectoryName(Host.TemplateFile);
        string outputFilePath = Path.Combine(templateDirectory, outputFileName);
        string output = this.GenerationEnvironment.ToString();
        File.WriteAllText(outputFilePath, output); 
    }

    this.GenerationEnvironment.Remove(0, this.GenerationEnvironment.Length);
}

所以在我的主.tt文件中,我有&lt;#@ includes ...#&gt;我的各种文件的.tt文件。例如:&lt;#@ include file =“DataObjectInterface.tt”#&gt;

<#+
    public string GenerateInterfaceDataObject(sqlTable table)
    {
        string ifaceName = "I" + table.ObjectName;
        if (table.GenerateInterfaceObjectAsBase)
        {
            ifaceName += "Base";
        }
#>
using System;

namespace <#= InterfaceNamespace #>
{
    public interface <#= ifaceName #>
    {
<#+
        foreach(sqlColumn col in table.Columns)
        {
#>
        <#= GetColumnCSharpDataType(col) #> <#= col.FieldName #> { get; }
<#+
        }
#>
    }
}
<#+
        return RootPath + @"\AutoGenerated\" + ifaceName + ".cs";
    }
#>

然后,在我的主要.tt课程中,我只是打个电话:

string filePath = GenerateInterfaceDataObject(table);
SaveOutput(filePath);

不确定这种破解模板的方法是否适合您的需求,但它对我的工作有效,我还没有遇到任何问题。

我应该澄清一下,我的主.tt文件实际上并没有生成任何东西。它本身不是一个模板。它只是加载每个模板并从其他模板生成文件。