【问题标题】:Why is this NuGet dependency missing when compiling .NET Framework project depending on .NET Standard?为什么在根据 .NET Standard 编译 .NET Framework 项目时缺少此 NuGet 依赖项?
【发布时间】:2019-11-03 23:28:23
【问题描述】:

我有一个包含 3 个项目的 Visual Studio 解决方案。

顶层是 .NET Framework 4.6.1 控制台应用程序(项目 A)。 它依赖于 .NET Framework 4.6.1 类库(项目 B)。 项目 B 依赖于 .NET Standard 2.0 类库(项目 C)。

我在项目 C 中有一些代码使用 System.Data.SqlClient(NuGet 包版本 4.6.1)。

由于以下已知问题https://github.com/dotnet/sdk/issues/901,我还将 System.Data.SqlClient 作为 NuGet 依赖项添加到项目 B(.NET Framework 类库)。

这是场景一,在构建解决方案时,System.Data.SqlClient被复制到项目A的/bin/Debug文件夹下,应用程序运行成功。

场景一的代码在这里https://github.com/JamesDunlop/TestDependencyFlowsNetStandard

但是,对于场景 2,我现在添加了对项目 A 的项目引用,这样它现在也直接引用/依赖于项目 C(即 .NET 标准类库)以及项目 B。这模仿了什么我需要在旧版应用程序中执行此操作。

清理、重建和运行。项目 A 的 /bin/Debug 文件夹中现在缺少 System.Data.SqlClient,并且在运行时出现异常“System.IO.FileNotFoundException: 'Could not load file or assembly 'System.Data.SqlClient”

为什么 System.Data.SqlClient 没有被复制到 /bin/Debug ?

请注意,我选择不将 .NET Framework 项目迁移到 PackageReferences 以解决问题 https://github.com/dotnet/sdk/issues/901,因为我需要在不可行的大型旧版 ASP.NET 解决方案中实现这一点。

我希望添加对项目 C 的引用不会产生什么影响,除了(如观察到的那样)它会导致更多的类型转发 DLL 被复制到 /bin/Debug 文件夹。但我不希望 System.Data.SqlClient 现在丢失。

【问题讨论】:

  • "2 此处列出的版本代表 NuGet 用于确定给定 .NET Standard 库是否适用的规则。虽然 NuGet 认为 .NET Framework 4.6.1 支持 .NET Standard 1.5 到 2.0,但使用为 .NET Framework 4.6.1 项目的这些版本构建的 .NET Standard 库存在几个问题。对于需要使用此类库的 .NET Framework 项目,我们建议您将项目升级到面向 .NET Framework 4.7 .2 或更高。” (docs.microsoft.com/en-us/dotnet/standard/net-standard)。也许有一些绳子可以拉上
  • 感谢@Sinaesthetic 的建议。我已经尝试将 .NET Framework 项目升级到 4.7.2,但不幸的是,上述问题仍然存在。
  • System.Data.SqlClient NuGet 包也添加到项目 A 应该可以解决它。对于场景 2,MSBuild 日志显示它尝试从项目 C 中解决此依赖关系,因为 .NET Standard 项目不会将其依赖关系复制到 bin 文件夹中,所以该项目在此处丢失。对于场景 1,MSBuild 从项目 B 中解析,成功。

标签: c# .net dll .net-standard dll-reference


【解决方案1】:

pfx 对原始问题的评论基本上回答了问题。

在场景 1 中,我们在构建日志中看到了这一点

3>  Dependency "System.Data.SqlClient, Version=4.5.0.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
3>      Resolved file path is "C:\dev\testing\TestDependencyFlowsNetStandard\TestDependencyFlows.Library\bin\Debug\System.Data.SqlClient.dll".

对于场景 2,MSBuild 不会尝试使用项目 B 的 bin 目录,并且构建日志显示了这一点,如 pfx 所述

3> For SearchPath "C:\dev\testing\TestDependencyFlowsNetStandard\TestDependencyFlows.Library.NetStandard\bin\Debug\netstandard2.0".
3>          Considered "C:\dev\testing\TestDependencyFlowsNetStandard\TestDependencyFlows.Library.NetStandard\bin\Debug\netstandard2.0\System.Data.SqlClient.winmd", but it didn't exist.
3>          Considered "C:\dev\testing\TestDependencyFlowsNetStandard\TestDependencyFlows.Library.NetStandard\bin\Debug\netstandard2.0\System.Data.SqlClient.dll", but it didn't exist.
3>          Considered "C:\dev\testing\TestDependencyFlowsNetStandard\TestDependencyFlows.Library.NetStandard\bin\Debug\netstandard2.0\System.Data.SqlClient.exe", but it didn't exist.

这种洞察力提供了解决方案 2 的解决方案。

使用此answer 中的解决方案,通过将<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> 添加到.NET Standard 项目C 的.csproj 中的<PropertyGroup>,System.Data.SqlClient 被复制到该.NET 项目的bin 目录中。 NET Standard 项目,然后 MSBuild 能够找到并将其复制到最终的构建输出文件夹。

编辑 - 上面的建议不起作用,因为在运行实际应用程序时,推送到输出目录的 DLL 用于错误的平台并且与 .NET Framework 不兼容。

作为进一步的信息,pfx 引用的构建日志可以在 Visual Studio IDE 中按照post 获得

pfx 建议在项目 A 中添加 System.Data.SqlClient 可行,但这是我想避免的,因为在真正的单体遗留应用程序中,需要添加项目 A 的许多等价物(而不是简单地将其添加到项目 B 的下一级)。

【讨论】:

    【解决方案2】:

    我将在这里重复我上面的评论,因为它被认为是有效的答案。

    MSBuild 日志的构建输出详细级别设置为 detailed 级别,可让您更深入地了解发生的情况。

    场景1(A引用B,B引用C)

    构建日志显示项目 A 成功地从项目 B 的 \bin\debug 文件夹中解析了其 System.Data.SqlClient 依赖关系并将其复制到本地。
    (由于项目 B 是一个 .NET Framework 类库,它的NuGet 依赖项确实会复制到其 bin 文件夹中。)

    Dependency "System.Data.SqlClient, Version=4.5.0.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
      Resolved file path is "C:\...\TestDependencyFlows.Library\bin\Debug\System.Data.SqlClient.dll".
    

    场景2(A引用B和C,B引用C)

    构建日志提到项目 A 尝试从 NET Standard 项目 C(和一些知名文件夹)解决其 System.Data.SqlClient 依赖关系,但不再从项目 B 中解决。
    (因为项目 C 是NET Standard 项目,它不会将其 NuGetdependencies 复制到其 bin 文件夹。)
    所有这些尝试都失败,并显示文件在这些位置不存在的消息。

    Dependency "System.Data.SqlClient, Version=4.5.0.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
      Could not resolve this reference. Could not locate the assembly "System.Data.SqlClient, Version=4.5.0.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a". 
      Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors.
      For SearchPath "C:\...\TestDependencyFlows.Library.NetStandard\bin\Debug\netstandard2.0".
          Considered "C:\...\TestDependencyFlows.Library.NetStandard\bin\Debug\netstandard2.0\System.Data.SqlClient.winmd", but it didn't exist.
          Considered "C:\...\TTestDependencyFlows.Library.NetStandard\bin\Debug\netstandard2.0\System.Data.SqlClient.dll", but it didn't exist.
          Considered "C:\...\TestDependencyFlows.Library.NetStandard\bin\Debug\netstandard2.0\System.Data.SqlClient.exe", but it didn't exist.
          ...
    

    解决方案可能是将System.Data.SqlClient NuGet 包也添加到项目 A。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-02
      • 2017-12-15
      • 2023-03-09
      • 2020-06-04
      • 2017-08-16
      • 1970-01-01
      • 2020-09-19
      相关资源
      最近更新 更多