T4引擎无法识别当前项目命名空间

时间:2013-01-31 17:04:02

标签: c# .net entity-framework-5 t4 self-reference

我正在使用VS 2010(C#)T4模板来生成代码。

我需要遍历项目中的所有类型,列出实体poco类并生成包装器。问题是,项目命名空间无法识别。

以下是解决方案结构:

namespace MySolution.Entities
{
    public class Employee { ... }
    public class Department { ... }
}

// Seperate project referenceing MySolution.Entities.
namespace MySolution.Database
{
    public partial class Context { ... }

    // Should generate Context.cs as a partial class with after iterating Syste.Types available in MySolution.Entities.
    Context.tt
}

以下是文字模板:

<#@ template language="C#" #>
<#@ Output Extension=".cs" #>

namespace MySolution.Database
{
    public partial class Context:
        System.Data.Entity.DbContext
    {
<#
System.Type [] types = typeof(MySolution.Entities).Assembly.GetTypes();
for (int i=0; i < types.Count; i++)
#>
        public <#= types[i].Name; #> <#= types[i].Name; #> { get; set; }
    }
}

上面的代码生成错误:找不到类型或命名空间“MySolution”。您是否缺少using指令或程序集引用?然后我将以下代码行包含在程序集中:

<#@ Assembly Name="..\MySolution.Entities\bin\x86\Release\MySolution.Entities.dll" #>

现在它给了我一个不同的错误:主机在尝试解析程序集引用'.. \ .. \ .. TrafficMonitor.Core \ bin \ x86 \ Release \ TrafficMonitor.Library.dll'时抛出异常。转换不会运行。抛出以下异常: System.IO.FileLoadException:给定的程序集名称或代码库无效。 (来自HRESULT的异常:0x80131047)

有关如何克服此限制的任何想法?

2 个答案:

答案 0 :(得分:3)

您无法静态引用尚未编译的程序集(请记住,T4在编译程序集之前运行) 有一篇很好的文章,你可以在How to use T4 to generate Decorator classes

上考虑到这一点

您也不应该通过<#@ Assembly Name引用程序集,因为T4将在已编译的程序集上运行,但T4在编译之前运行。因此,您的工作流程将是 - 编译应用程序,运行t4,使用来自t4的新源重新编译应用程序。并且每次在源代码中更改后,T4正在运行。

答案 1 :(得分:3)

错误是因为T4模板处理器无法找到您的程序集。

如果在T4模板的Assembly指令中使用程序集的完整路径,它应该找到程序集。使用完整路径的更好方法是使用Visual Studio宏变量之一,例如$(SolutionDir),它将在执行T4模板时进行扩展。

<#@ Assembly Name="$(SolutionDir)MySolution.Entities\bin\x86\Release\MySolution.Entities.dll" #>