13

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

所以我的设置很简单:

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

ProjectBProjectA的引用是通过References -> Add Reference... -> Solution -> ProjectA 添加的。

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

有任何想法吗?

4

3 回答 3

19

解释

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

所以依赖链看起来像这样:Y => X => A => B

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 的文件中。

出于几个原因,我个人更喜欢选项 2。

  1. 如果您将来添加另一个引用项目 X 的​​项目,则不必记住还包括对程序集 B 的引用(就像您必须使用选项 1 一样)。
  2. 您可以有明确的评论说明为什么需要有虚拟代码而不是删除它。因此,如果有人不小心删除了代码(比如使用查找未使用代码的重构工具),您可以轻松地从源代码管理中看到代码是必需的并恢复它。如果您使用选项 1 并且有人使用重构工具来清理未使用的引用,那么您没有任何评论;您只会看到从 .csproj 文件中删除了一个引用。

这是我遇到这种情况时通常添加的“虚拟代码”示例。

    // 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);
    }
于 2014-01-10T22:27:20.273 回答
13

如果依赖关系图比您描述的更复杂,您可能会遇到一些版本控制问题。

  1. 将编译器输出设置为诊断以查看发生了什么:VS->Options->Projects and Solutions->Build and Run->MSBuild project build output vervosity:->Diagnostic 在此处输入图像描述
  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. 尝试在任何地方使用相同的依赖版本修复该问题,然后再次编译。
于 2013-11-10T12:40:13.043 回答
0

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

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

于 2013-10-28T23:38:58.257 回答