Как создать «Проект управления пакетами NuGet» для .NET Standard? - PullRequest
1 голос
/ 14 июня 2019

Я хотел бы поработать с проектом, единственной точкой которого является ссылка на пакеты NuGet, которые (вместе со всеми их зависимостями) будут затем загружаться и обновляться Visual Studio (в настоящее время для меня 2017). 1 (Это похоже на то, что описано в другой вопрос .)

Когда я создаю проект .NET Framework 4.7.1, я могу использовать VS Управление пакетами NuGetФункция для выбора нужных пакетов, VS загрузит пакеты в каталог решения, и мои сценарии сборки могут выяснить, какие библиотеки DLL скопировать в мои действительные папки проекта, основываясь на информации, найденной в файле .csproj (<HintPath> и такие).

Когда я делаю то же самое с проектом .NET Standard 2.0, VS будет использовать новый упрощенный формат .csproj.Все, что он упоминает о (явно и транзитивно) требуемых пакетах, - это отдельный элемент <PackageReference>, содержащий только имя и версию пакета для каждого пакета, на который я явно выбрал ссылку.Моим сценариям недостаточно для трансплантации ссылок в целевой файл .csproj. 2

Есть ли еще хороший способ управления пакетами NuGet с помощью такого фиктивного проекта при нацеливании.NET Standard (2.0)?


1 : Причины этого включают большое количество индивидуальных решений, многие из которых требуют одинаковых пакетов, и где не всеразработчики должны сами управлять этими пакетами, а также средами, которые не поддерживают NuGet самостоятельно (например, игровой движок Unity, поэтому отдельный проект для управления ссылками NuGet и извлечения ссылок - это путь ).

2 : Даже если в проекте Unity настроен «Уровень совместимости API» - «.NET Standard 2.0», в файле .csproj, созданном Unity, будет использоваться подробный «старый стиль».формат (и, кажется, на самом деле нацелены на .NET Framework 4. *) и соответственно ожидают явного пути к ссылочным библиотекам.

1 Ответ

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

Как я уже упоминал в качестве комментария к вопросу, игнорирование сносок на вопрос выглядит как общий вопрос .NET, и я ожидаю, что Google предложит эту страницу людям, выполняющим общий поиск, не ограничиваясь Unity, и не будет Для других людей, читающих вопрос, очевидно, что это характерно для Unity, пока они не прочитают большую часть вопроса. Поэтому я собираюсь начать с ответа на общую разработку .NET.

Если все задействованные проекты используют PackageReference, то ничего особенного делать не нужно. Просто создайте .NET Standard Class Library из нового шаблона проекта, добавьте ссылки на пакеты к нужным пакетам, затем создайте ссылки на проекты на вашу библиотеку классов из приложений, которые вы хотите использовать этот набор пакетов NuGet.

Если у вас есть проект не в стиле SDK, в котором нет пакетов, добавьте <PackageRestoreStyle>PackageReference</PackageRestoreStyle>. Причина в том, что PackageReference был добавлен в NuGet спустя годы после запуска NuGet, при этом первоначальный способ использования пакетов был packages.config. Поэтому, если проект не поддерживает PackageReference стиль восстановления, по умолчанию используется packages.config. Смотрите следующий абзац.

Если у вас есть проект в стиле, отличном от SDK, который использует packages.config (или не имеет пакетов и не выбрал PackageReference стиль восстановления), этот подход может не работать. Система сборки создаст сборку приложения и, вероятно, скопирует все ссылки, на которые непосредственно ссылаются в csproj, что означает, что она получит вашу dll библиотеки классов, а также любые пакеты nuget, на которые есть прямые ссылки. Однако, поскольку приложение csproj не знает о пакетах NuGet вашей библиотеки классов, они не будут скопированы. Обычно библиотека классов ссылается на пакеты, которые она использует, и система сборки .NET будет использовать что-то под названием ResolveAssemblyReferences , чтобы посмотреть на библиотеку библиотеки классов, посмотреть, какие у нее зависимости, затем скопировать эти библиотеки. Однако в этом случае проект библиотеки классов не имеет скомпилированных зависимостей, поскольку он никогда не использовал ни один из пакетов NuGet, на который ссылается проект.

Это одна из причин, по которой команды NuGet и .NET поощряют пользователей переходить на PackageReference. Существует множество проблем, таких как транзитивные зависимости, и <HintPath> работает плохо, когда проекты перемещаются, которые работают намного лучше, если поддерживаемый тип проекта.

Теперь, учитывая, что в вопросительной сноске упоминается, что спрашивающий хочет сделать это для проекта Unity, я дам ответ, который, надеюсь, сработает. Обратите внимание, что, работая в клиентской команде NuGet, я ничего не знаю о Unity и потратил впустую около 2 часов моего сегодняшнего дня, устанавливая его и пытаясь понять его возможности, просто чтобы обнаружить, что Unity не поддерживает ни NuGet, ни проект. ссылки вообще.

Поэтому я предлагаю либо:

используйте dotnet publish, чтобы система сборки .NET скопировала все соответствующие библиотеки в одну папку, куда вы можете ссылаться в проекте Unity

или

Многоцелевая библиотека классов, предназначенная для .NET Standard 2.0 и .NET Framework 4.7.1 (отрегулируйте версию .NET Framework так, чтобы она использовалась так же, как в вашем проекте Unity). Сделайте это, изменив <TargetFramework>netstandard2.0</TargetFramework> на <TargetFrameworks>netstandard2.0;net471</TargetFrameworks> (обратите внимание, что к элементу XML добавлен s в конце). Теперь, когда вы создаете библиотеку классов, .NET SDK создаст две директории в каталоге bin\, по одной для каждой целевой платформы. В настоящий момент, по крайней мере, кажется, что каталог net471 получает все dll, похожие на проекты не в стиле SDK.

...