Было предложено разбить библиотеки .netstandard на их собственный пакет NuGet, это ответ или я что-то упустил?
По сути, да, разделение пакета ответ. Другой возможностью является перемещение сборок netstandard в папку net47 или сборок net47 в папку netstandard2.0, но в любом случае есть проблемы. Хотя решение состоит в том, чтобы перекомпилировать все ваши сборки, чтобы все они использовали одну и ту же целевую среду, но у нее также есть свои проблемы.
Если вы прочитали документы NuGet и пришли к выводу, что то, что вы пытаетесь, должно пожалуйста, укажите, какие документы заставляют вас в это верить, поэтому я могу обновить документы и попытаться устранить путаницу.
Первое, что нужно понять о том, почему NuGet поддерживает пакет, имеющий несколько папок целевого каркаса, это потому что пакет может использовать новые возможности фреймворка, где это возможно, но иметь поддержку пользователей пакета, использующих старые фреймворки. Поэтому автору пакета требуется несколько версий их сборки, в зависимости от того, какая из них совместима с проектом пользователя. Итак, дело в том, что NuGet нужно выбирать активы из пакета в зависимости от того, какой целевой моникер структуры (TFM) использует проект. NuGet на самом деле делает выбор активов следующим образом:
NuGet смотрит, какие папки TFM существуют в пакете, чтобы получить список TFM, которые поддерживает пакет. Обычно он ищет папки lib/<tfm>/
и ref/<tfm>
, но файлы contentFiles/<tfm>
и build/<tfm>
также могут быть релевантными. Обратите внимание, что он не смотрит ни на какие имена файлов. Какие сборки существуют в lib/net47/*.dll
или lib/netstanard2.0/*.dll
, пока не рассматриваются.
Получив этот список пакетов TFM, он смотрит на проект TFM и выбирает «лучший» TFM. Для проектов стиля SDK, которые многоцелевые, он делает это один раз для проекта TFM. «Лучший» TFM означает одно и то же «семейство» (net* проекты всегда выбирают net* активов, если они доступны. Только при отсутствии net* сборок совместим с netstandard. NET Framework TFM ищет netstandard * активов) .
Как только TFM пакета выбран для TFM проекта, NuGet выбирает все файлы, такие как lib/<tfm>/*.dll
, ref/<tfm>/*.dll
, contentFiles/<tfm>/<lang>/*
, build/<tfm>/<package_id>.<props|targets>
и т. Д.
Итак, вы можете видеть, что если ваш пакет содержит lib/net47/assembly1.dll
и lib/netstandard2.0/assembly2.dll
, NuGet будет выбирать только одну из двух сборок, но не обе одновременно, в зависимости от того, является ли net47 или netstandard2.0 более совместимым с проектом.
Хотя для вас может показаться желательным, чтобы NuGet делал выбор TFM для каждого TFM, а не сначала выбирал TFM, а затем выбирал только сборки, которые существуют в этой папке, подумайте, когда пакет добавляет дополнительную вспомогательную утилиту в «polyfill» old TFM с функциями, которые пакет использует в более новых TFM. Эта вспомогательная утилита не нужна для новых TFM, поэтому для NuGet было бы нежелательно выбирать ее.
Команда NuGet предлагает создать один пакет на сборку, и в этом случае такая проблема никогда бы не возникла, поскольку NuGet сделали выбор ресурса для каждого пакета, и при условии, что каждый пакет был создан правильно, все просто выбирает правильно выбранный. Если вы настаиваете на объединении всех сборок в один пакет, из моего описания выше, я надеюсь, вы увидите, что вам нужно поместить все сборки в одну папку TFM, но, поскольку разные сборки были скомпилированы для разных TFM, есть вероятность проблем, особенно если некоторые разработчики используют более старые версии Visual Studio, которые могут не поддерживать. NET Стандарт. Я настоятельно рекомендую по крайней мере создать один пакет для TFM или перекомпилировать все сборки для использования одного и того же TFM.