10

我有一个 Visual Studio 解决方案,有 3 个项目。

顶层是 .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文件夹中,应用程序运行成功。

场景 1 的代码在这里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 现在丢失。

4

2 回答 2

5

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

MSBuild日志的构建输出详细程度设置为 level detailed,可以更深入地了解发生的情况。

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

构建日志显示项目A成功System.Data.SqlClient从项目B的文件夹中解析了它的依赖\bin\debug并复制到本地。
(由于项目 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 尝试System.Data.SqlClient从项目 C(和一些众所周知的文件夹)解决其依赖关系NET Standard,但不再从项目 B解决。
(因为项目 C 是一个NET Standard项目,它不会将其NuGet依赖项复制到其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.SqlClientNuGet 包也添加到项目 A。

于 2019-06-26T05:43:52.593 回答
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 不会尝试使用bin项目 B 的目录,并且构建日志显示了这一点,如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 的解决方案。

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

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

作为进一步的信息,pfx引用的构建日志可以根据这篇文章在 Visual Studio IDE 中获取

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

于 2019-06-26T00:03:27.267 回答