Как создать пакет .NET Standard NuGet с минимальными зависимостями в VS 2017?

В настоящее время я выполняю миграцию проекта библиотеки для поддержки .NET Standard 1.1 с помощью Visual Studio 2017.

Я надеялся выпустить проект как единый пакет NuGet, который может ориентироваться как на .NET Framework 4.5+, так и на .NET Core, UWP и т.д.

Однако, когда я пытаюсь установить полученный пакет в проектах .NET Framework, создается огромный список зависимостей пакетов, содержащий все пакеты, определенные в стандарте .NET(см. ниже):

Зависимости пакетов после установки в проекте .NET 4.5.

Я понимаю, что это все сборки, определенные как часть спецификации .NET Standard 1.1. Однако для моего конкретного проекта на самом деле требуется только крошечный набор из них, и этот список зависимостей будет чрезвычайно запутанным для тех, кто устанавливает пакет в своих проектах.

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

Однако ответ был в контексте старого формата project.json, который теперь был заменен новым .csproj-форматом в VS 2017. Я попытался удалить зависимость от метаклапа .NET Standard 1.1, удалив <TargetFramework>, но мне удалось сломать сборку и не удалось найти способ специально добавить только необходимые зависимости.

Обещание перемещать библиотеки в .NET Standard для максимальной совместимости с платформой чрезвычайно привлекательно, но что является рекомендуемым способом структурирования зависимостей, так что проекты, ориентированные на "классическую".NET Framework, не находят своих проектов "загрязненными" всеми эти зависимости?

Ответ 1

Измените <TargetFramework> на <TargetFrameworks> и добавьте к нему ;net45. Вы все равно получаете один вывод пакета NuGet, но теперь он будет тянуть только дополнительные зависимости, если вы нацеливаете основное приложение .NET(которое уже будет иметь зависимости).

Ответ 2

Во-первых, я хотел бы указать, что это в основном проблема времени разработки и не влияет на результирующие приложения и переносимость ваших библиотек:

В прошлом мы дали разработчикам рекомендацию не ссылаться на мета-пакет (NETStandard.Library) из пакетов NuGet, а вместо этого ссылаться на отдельные пакеты, например System.Runtime и System.Collections. Обоснованием было то, что мы думали о мета-пакете как сокращении для пакета пакетов, которые были фактическими атомными строительными блоками платформы .NET. Предполагалось: мы могли бы создать еще одну платформу .NET, которая поддерживает только некоторые из этих атомных блоков, но не все из них. Были также опасения относительно того, как наши инструменты имеют дело с большими графами пакетов.

Двигаясь вперед, мы упростим это:

  • Стандарт .NET - это атомный строительный блок. Другими словами, новым платформам не разрешено подмножество .NET Standard - им нужно реализовать все это.

  • Мы отказываемся от использования пакетов для описания наших платформ, включая .NET Standard.

Это означает, что вам больше не придется ссылаться на все пакеты NuGet для .NET Standard. Вы указали свою зависимость с папкой lib, и именно так она работает для всех других платформ .NET, в частности .NET Framework.

Однако, сейчас наша инструментальная система все равно будет записываться в ссылке на NETStandard.Library. В этом нет никакого вреда, он просто станет излишним движением вперед.

Однако я полностью признаю, что этот результат вряд ли желателен.

С .NET Standard 1.x и packages.config у вас, к сожалению, нет выбора, кроме как создать рукописный .nuspec с настраиваемыми группами зависимостей. Однако для этого требуется понимание того, какие пакеты требуются, и имеет тенденцию быть хрупкими. Если потребитель использует <PackageReference>, он немного меньше головной боли, потому что он отделяет прямые - от транзитивных ссылок, и, следовательно, это не так много в вашем лице.

С .NET Standard 2.0 проблема полностью исчезнет.

Ответ 3

Если вы посмотрите на эти ссылки на пакеты для net45, вы обнаружите, что фактическая DLL не загружается. Пакет там, так что время выполнения, такое как coreclr, который загружает все части BCL, как dll, может получить их. Однако в net45 вы фактически не найдете DLL в этих пакетах.

Короче говоря, в .net 4.x,.net все равно будет использовать GAC для загрузки этих сборок.