Сочетание DLL-файлов .netstandard2.0 и .netframework47 в пакете nuget - .netstandard недоступно - PullRequest
0 голосов
/ 06 января 2020

Прежде всего, я не знаю, является ли то, что я делаю, в корне неправильной идеей, поэтому ответ может быть просто не делать этого, но здесь идет ..

У меня есть пакет, который Я создаю из файла .nuspe c, в разделе «файлы» он содержит ссылки на стандартные библиотеки. net и. net. Он также имеет зависимости как от .netstandard20, так и от .netframework47.

Причиной этого является то, что устаревшие библиотеки написаны в фреймворке, а новые - стандартно.

У нас есть потребляющий проект (на самом деле, несколько), написанный на .netframework 4.7, который должен адресовать оба набора библиотек DLL. Я изменил проект, чтобы использовать PackageReference, а не packages.config, и Visual Studio показывает, что на пакет ссылаются (а не на отдельные пространства имен) в разделе «Ссылки». Когда я собираю, DLL-библиотеки .netframework копируются в папку bin, но не в DLL-библиотеку .netstandard.

Я создал рабочий проект, чтобы изолировать проблему, и там я вижу то же самое. , Проект в основном просто отказывается признать стандартный. Если я добавляю оператор using в класс с типом из DLL-библиотеки .netstandard, он просто помещает красный волнистый слой под ним и говорит, что его нет в пространстве имен.

Было предложено, чтобы я нарушил .netstandard DLL в свой собственный пакет NuGet, это ответ или я что-то упустил?

Вот несколько примеров ..

Файл .nuspe c:

<?xml version="1.0" encoding="utf-8"?>
<package >
  <metadata minClientVersion="2.5">
    <!-- other tags removed for brevity -->
    <dependencies>
      <group targetFramework=".NETStandard2.0"></group>
      <group targetFramework=".NETFramework4.7">
        <dependency id="NLog" version="3.1.0.0" />
      </group>
    </dependencies>
  </metadata>
  <files>
    <file src="..\Src\MyProj1\bin\Release\netstandard2.0\NetStandardClass.dll" target="lib\netstandard2.0" />
    <file src="..\Src\MyProj2\bin\Release\NetFrameworkClass1.dll" target="lib\net47" />
    <file src="..\Src\MyProj3\bin\Release\NetFrameworkClass2.dll" target="lib\net47" />
  </files>
</package>

Пакет упоминается как пакет, а не отдельные типы в нем:

enter image description here

Если я пытаюсь вручную добавить оператор использования, ссылающийся на пространство имен NetStandardClass, он помечается как ошибка

enter image description here

Сам пакет содержит все 3 DLL, как и ожидалось:

enter image description here

Тем не менее, когда я собираю проект и проверяю папку bin, NetStandardClass DLL не существует: enter image description here

1 Ответ

0 голосов
/ 06 января 2020

Было предложено разбить библиотеки .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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...