Почему эта зависимость NuGet отсутствует при компиляции проекта .NET Framework в зависимости от .NET Standard? - PullRequest
5 голосов
/ 21 июня 2019

У меня есть решение Visual Studio с 3 проектами.

Верхним уровнем является консольное приложение .NET Framework 4.6.1 (проект A).Это зависит от библиотеки классов .NET Framework 4.6.1 (проект B).Проект B зависит от библиотеки классов .NET Standard 2.0 (проект C).

У меня есть некоторый код в Project C, который использует System.Data.SqlClient (версия пакета NuGet 4.6.1).

Из-за следующей известной проблемы https://github.com/dotnet/sdk/issues/901 я также добавил System.Data.SqlClient в качестве зависимости NuGet к проекту B (библиотеке классов .NET Framework).

Это сценарий 1, иКогда решение построено, System.Data.SqlClient копируется в папку / bin / Debug проекта A, и приложение успешно выполняется.

Код для сценария 1 находится здесь https://github.com/JamesDunlop/TestDependencyFlowsNetStandard

Однако для сценария 2 я теперь добавляю ссылку проекта на проект А, так что теперь он также напрямую ссылается на проект С (т. Е. Стандартную библиотеку классов .NET), а также на проект Б.нужно будет сделать в унаследованном приложении.

Очистить, перестроить и запустить.System.Data.SqlClient теперь отсутствует в папке / bin / Debug проекта A, и во время выполнения возникает исключение «System.IO.FileNotFoundException:« Не удалось загрузить файл или сборку »System.Data.SqlClient"

Почему System.Data.SqlClient не копируется в / bin / Debug?

Обратите внимание, что я решил НЕ переносить проекты .NET Framework в PackageReferences для решения проблемы https://github.com/dotnet/sdk/issues/901,, поскольку мне нужно реализовать это в большом устаревшем решении ASP.NET, где это невозможно.

Я ожидаю, что добавление ссылки на Project C будет иметь небольшой эффект, кроме (как было отмечено) это приводит к тому, что в папку / bin / Debug копируется гораздо больше библиотек переадресации типов.Но я бы не ожидал, что System.Data.SqlClient будет отсутствовать.

Ответы [ 2 ]

2 голосов
/ 26 июня 2019

Я повторю свой комментарий выше здесь, так как он считается действительным как ответ.

Журнал MSBuild, с выходной подробностью сборки, установленной на уровень detailed, дает больше информации о том, что происходит.

Сценарий 1 (A, ссылающийся на B, B, ссылающийся на C)

Журнал сборки показывает, что проект A успешно разрешил свою System.Data.SqlClientзависимость из папки \bin\debug проекта B и копирует ее локально.
(Поскольку проект 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 отNET Standard проект C (и некоторые известные папки), но больше не из проекта B.
(Поскольку проект C является проектом NET Standard, он не копирует свои NuGet зависимости в его bin folder.)
Все эти попытки завершаются неудачно с сообщением, что файл dих нет в этих местах.

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.
      ...

Решением может быть добавление пакета NuGet System.Data.SqlClient также в проект A.

1 голос
/ 26 июня 2019

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.

Используя решение в этом ответе , добавив <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> к <PropertyGroup> в .csproj для .NET Standard Project C, System.Data.SqlClient копируется в bin каталог этого проекта .NET Standard, и MSBuild сможет найти и скопировать его в выходную папку окончательной сборки.

РЕДАКТИРОВАТЬ - приведенное выше предложение не работает, поскольку при запуске реального приложения DLL, помещаемая в выходной каталог, предназначена для неправильной платформы и несовместима с .NET Framework.

В качестве дополнительной информации журналы сборки, на которые ссылается pfx , могут быть получены в Visual Studio IDE согласно этой публикации

pfx предложение о добавлении System.Data.SqlClient в проект А работает, но этого я хотел избежать, потому что в реальном монолитном унаследованном приложении есть много эквивалентов для проекта А, где его нужно было бы добавить (вместо того, чтобы просто добавить его на следующий уровень вверх по Проекту B).

...