NuGet包未从引用的项目中复制

时间:2013-10-22 20:06:18

标签: visual-studio reference nuget

我有一个非常奇怪的错误,我没有解释。

所以我的设置非常简单:

我有一个包含2个项目的解决方案,我们将它们命名为 ProjectA ProjectB ProjectA 引用了一些NuGet包,如果构建 ProjectA ,我可以看到输出目录中的所有程序集, bin 文件夹。 ProjectB 现在引用 ProjectA ,但是如果我构建 ProjectB ,我在输出目录中有 ProjectA 程序集,但是而不是 ProjectA 引用的NuGet包。

ProjectB ProjectA 的引用随引用 - >一起添加添加参考... - >解决方案 - >项目A

我还创建了一个涵盖这个案例的小测试项目,但它在我的测试项目中运行得很好。

有什么想法吗?

3 个答案:

答案 0 :(得分:15)

说明

对于示例场景,假设我们有项目X,程序集A和程序集B.程序集A引用程序集B,因此项目X包含对A和B的引用。此外,项目X包含引用程序集A的代码(例如A.SomeFunction())。现在,您创建一个引用项目X的新项目Y。

因此依赖关系链如下所示: Y => X => A =>乙

Visual Studio / MSBuild试图变得聪明,只将引用引入到项目Y中,它检测到项目X需要它;这样做是为了避免项目Y中的参考污染。问题是,由于项目X实际上不包含任何明确使用程序集B的代码(例如B.SomeFunction()),VS / MSBuild不会检测到B是必需的通过X,因此不会将其复制到项目Y的bin目录中;它只复制X和A程序集。

解决方案

您有两个选项可以解决此问题,这两个选项都会导致程序集B被复制到项目Y的bin目录中:

  1. 在项目Y中添加对程序集B的引用。
  2. 将虚拟代码添加到项目X中使用程序集B的文件中。
  3. 就个人而言,我个人更喜欢选项2。

    1. 如果您将来添加另一个引用项目X的项目,则不必记住还包含对程序集B的引用(就像您必须使用选项1一样)。
    2. 你可以有明确的评论说明为什么虚拟代码需要存在而不是删除它。因此,如果有人确实删除了代码(比如使用查找未使用代码的重构工具),您可以从源代码控制中轻松地看到代码是必需的并恢复它。如果您使用选项1并且某人使用重构工具来清理未使用的引用,则您没有任何注释;您将看到从.csproj文件中删除了引用。
    3. 以下是我遇到这种情况时通常会添加的“虚拟代码”示例。

          // DO NOT DELETE THIS CODE UNLESS WE NO LONGER REQUIRE ASSEMBLY A!!!
          private void DummyFunctionToMakeSureReferencesGetCopiedProperly_DO_NOT_DELETE_THIS_CODE()
          {
              // Assembly A is used by this file, and that assembly depends on assembly B,
              // but this project does not have any code that explicitly references assembly B. Therefore, when another project references
              // this project, this project's assembly and the assembly A get copied to the project's bin directory, but not
              // assembly B. So in order to get the required assembly B copied over, we add some dummy code here (that never
              // gets called) that references assembly B; this will flag VS/MSBuild to copy the required assembly B over as well.
              var dummyType = typeof(B.SomeClass);
              Console.WriteLine(dummyType.FullName);
          }
      

答案 1 :(得分:11)

如果依赖图比您描述的更复杂,则可能会出现一些版本问题。

  1. 将编译器输出设置为诊断以查看发生的情况:VS->选项 - >项目和解决方案 - >构建和运行 - > MSBuild项目构建输出的真实性: - >诊断 enter image description here
  2. 编译解决方案。如果您发现类似的问题:
      

    “X,Version = 2,Culture = neutral,PublicKeyToken = null”和“X,Version = 1,Culture = neutral,PublicKeyToken = null”之间存在冲突。

         

    “X,Version = 2,Culture = neutral,PublicKeyToken = null”被选中,因为它是主要的,“X,Version = 1,Culture = neutral,PublicKeyToken = null”不是。

  3. 尝试在任何地方使用相同的依赖版本修复该问题,然后重新编译。

答案 2 :(得分:0)

您的ProjectA是否使用通过NuGet软件包安装的程序集?

如果在ProjectA中使用程序集中的类型,那么构建ProjectB会将它们放在输出目录中。