无法在T4模板中引用程序集

32

我在我的主程序集PocoGenerator的测试类中有以下代码。该程序集应该使用T4模板,根据引用程序集(一个项目引用)DataObjects中的L2S实体生成POCO。

var assemblyName = "DataObjects";
var dataObjects = AppDomain.CurrentDomain.Load(new AssemblyName(assemblyName));

尽管我尝试了各种形式的assembly指令,但我仍然无法让T4找到DataObjects程序集。

<#@ assembly name="DataObjects" #>
<#@ assembly name="DataObjects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" #>

我已经尽力了,但没有结果。上面的代码在测试类中有效,但在模板中无效。我做错了什么?

补充: 我通过在引用它的两个位置(指令和类特性块)中使用程序集的绝对路径来解决了这个问题。

<#@ assembly name="C:\Development\PocoGenerator\DataObjects\bin\Debug\DataObjects.dll" #>
并且
var sourceAssembly = Assembly.LoadFile(@"C:\Development\PocoGenerator\DataObjects\bin\Debug\DataObjects.dll");

但是我真的不喜欢这样,因为我想在不同的项目中使用这个模板,而且我非常讨厌重复,特别是魔术字符串。


你的模板项目应该有一个对你所依赖的项目的项目引用。你上面的"assembly"标签看起来没问题。你还应该有一个"import"引用。你具体收到了什么错误信息?(还有AppDomain的东西是怎么回事?你不应该做任何像那样的事情) - Kirk Woll
AppDomain的作用是允许我遍历当前AppDomain中加载的一个程序集中的所有类型,这与引用模板本身的程序集无关。 - ProfK
是的,我现在明白了。那么你收到了什么确切的错误消息? - Kirk Woll
1
@Kirk,请查看我的最新编辑。 - ProfK
4个回答

54
<#@ assembly name="$(ProjectDir)bin\Debug\ProofOfConcept.dll" #>

开心编程!


1
请注意,这是仅适用于VS2010的功能。 - GarethJ
30
甚至更好的是: <#@ assembly name="$(ProjectDir)$(OutDir)$(TargetFileName)" #>。 (说明:这是一段代码,用于在 Visual Studio 中指定程序集的路径。) - Jürgen Steinblock
13
最简翻译:<#@ 程序集名称="$(TargetPath)" #> - pylover
5
这只适用于项目已经构建的情况,如果希望在项目构建前使用引用程序集生成代码,该怎么办? - Sean Glover
1
我找到了一个在我的使用情况下很好的解决方案。在您的解决方案中创建另一个项目,具有相同的引用(可以通过NuGet进行批量更新),更新构建顺序,将其构建输出配置为某个确定性位置(即$(SolutionDir)..\MyT4Assemblies),并使具有T4模板的任何项目依赖于它首先构建。 https://dev59.com/lWDVa4cB1Zd3GeqPeIWp#9354103 - Sean Glover
显示剩余2条评论

15

在VS2010的T4模板中引用程序集有几种选择:

  1. 将程序集GAC并使用命名空间引用或完全限定类型名
  2. 使用硬编码的完全限定UNC路径
  3. 将程序集复制到Visual Studio的“公共程序集文件夹”中,并使用命名空间引用或完全限定类型名。
  4. 使用或定义Windows环境变量构建完全限定UNC路径。
  5. 使用Visual Studio宏来构建完全限定UNC路径。

我建议将所需的程序集放置于"Public Assemblies Folder"文件夹下,另一个甚至更好的解决方法是硬编码你的程序集的路径。

这里有一篇关于该主题很好的文章:T4 Template error - Assembly Directive cannot locate referenced assembly in Visual Studio 2010 project.

基本上,微软决定进行重大改变,即项目引用的程序集不会由T4引擎引用。

T4的程序集集合与包含项目的程序集集合完全分离,以避免在项目针对早期框架版本时选择错误的程序集。项目程序集不再用于解析模板程序集指令。

更多相关信息请参考:Visual Studio 2010中T4的新功能


+1 对于不再使用项目引用,这让我感到非常解脱! - dbones
@Peter Stegnar,我在这里提出了一个相关的问题:http://stackoverflow.com/questions/13838142/put-all-methods-in-one-tt-file-and-use-it-in-another-t4-files-in-codetemplates 请您查看一下。 - Saeid

1

当我尝试在我的Web项目中包含Less Css for .NET时,我遇到了类似的问题。

最终我将程序集复制到项目的根文件夹中,并将其作为引用包含在项目中。然后,我在.tt文件中添加了以下行:

<#@ assembly name="dotless.Core.dll" #>

<#@ import namespace="dotless.Core" #>
<#@ import namespace="dotless.Core.configuration" #>

我相信类似的方法也适用于你的汇编语言...


0

我发现在创建和使用gax工具包和软件包时,经常会出现这样的情况:编译过程中通常不会有问题,但在运行时可能会出现错误,因为找不到所需的东西 - 这通常发生在主程序集引用了一个使用gax元素的程序集,然后该程序集又引用了主程序集没有的另一个程序集。

尝试直接将相关程序集包含在主程序集中 - 并考虑您可能需要编写后生成指令来移动它到“预期”的位置 - 尽管有些麻烦,但这应该比硬编码路径要好。

你的结果可能会有所不同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接