Пакеты многоцелевых библиотек .NETStandard не восстанавливаются при сборке.

Фон:

Я создал многоцелевую библиотеку, предназначенную для net40, net462 и netstandard2.0. Цель этой библиотеки — обернуть StackExchange.Redis и некоторую связанную логику повторного подключения. Для net40 мне нужно использовать более старую версию пакета, чем более новые цели. Вот мой файл csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFrameworks>net40;net462;netstandard2.0</TargetFrameworks>
  </PropertyGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
    <PackageReference Include="StackExchange.Redis">
      <Version>2.0.513</Version>
    </PackageReference>
  </ItemGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'net462'">
    <PackageReference Include="StackExchange.Redis">
      <Version>2.0.513</Version>
    </PackageReference>
  </ItemGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'net40'">
    <PackageReference Include="StackExchange.Redis.StrongName">
      <Version>1.1.608</Version>
    </PackageReference>
  </ItemGroup>

</Project>

Как правило, эта библиотека работает и может использоваться приложениями на разных целевых платформах.


Проблема:

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

  • Когда я строю в Visual Studio,

    • Я получаю несколько случаев этой ошибки из проектов, которые косвенно ссылаются на мой многоцелевой проект:

      Сборка восстановила пакеты NuGet. Снова соберите проект, чтобы включить эти пакеты в сборку. Дополнительные сведения см. на странице http://go.microsoft.com/fwlink/?LinkID. =317568.

    • Я также получаю еще много случаев этой ошибки из различных проектов, которые прямо или косвенно ссылаются на мою многоцелевую библиотеку. {Identifier} и {Namespace} различаются, некоторые относятся к объектам в моей многоцелевой библиотеке, некоторые относятся к объектам в проектах, которые зависят от этого.

      CS0234 Имя типа или пространства имен «{Идентификатор}» не существует в пространстве имен «{Пространство имен}» (вам не хватает ссылки на сборку?)

    • Если я соберу второй раз, как предполагает первая ошибка, я получу те же ошибки.

  • Если я щелкну решение правой кнопкой мыши в Обозревателе решений и выберу Восстановить пакеты Nuget после сборки, ничего не произойдет и появится сообщение: Все пакеты уже установлены, и нечего восстанавливать.

  • Если я выберу Инструменты > Диспетчер пакетов Nuget > Консоль диспетчера пакетов и введу команду dotnet restore, сборка будет работать без ошибок.

Этот проект — единственный в решении, в котором используется мультитаргетинг и формат ссылки на пакет csproj <PackageReference>.

Мне нужно, чтобы пакеты восстановления были интегрированы в мою сборку, чтобы

  • Мне не нужно объяснять коллегам, как обойти проблему с помощью Консоли диспетчера пакетов.
  • Я могу создать это решение с помощью сторонних инструментов, таких как TeamCity, без дополнительной настройки.

Неудачные попытки:

Вот несколько вещей, которые я пробовал до сих пор:

  • Добавлено dotnet restore в качестве события перед сборкой проекта. Это ничего не делает.
  • Использовали расширение События сборки решения Visual Studio для запуска dotnet restore в качестве события перед сборкой решения. Это работает локально, но это расширение, как правило, ненадежно и не поможет со сторонними сборками, такими как TeamCity.
  • Обновите файл csproj, чтобы использовать старый формат ссылки на пакет с файлом packages.config. Это внесло много новых ошибок сборки.

Обновления

  • Из командной строки я получаю сотни ошибок CS0246 (Не удалось найти тип имени пространства имен «Foo» (вы пропустили директиву using или ссылку на сборку?)) и ошибки CS0234, некоторые даже относятся к для типов в библиотеках базовых классов, таких как System.Net. Использование переключателя -restore, похоже, не меняет этого. Я могу что-то упустить из-за количества вывода.

  • Вот минимальный пример, который показывает подобное поведение: https://github.com/JamesFaix/RestoreFailExample Он генерирует единственная ошибка CS0246, которая немного отличается. Это также все еще терпит неудачу, когда я пытаюсь dotnet restore в консоли диспетчера пакетов.

  • Я использую VS 15.9.9


Я попробовал решение @Martin Ulrich. Похоже, это не сработало без обновления ссылок в моих csproj файлах и удаления package.config файлов. Для этого я использовал встроенное преобразование Visual Studio из старого формата в формат PackageReference.

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

Не удалось найти {папку проекта}\packages.config. Убедитесь, что в этом проекте установлен пакет Microsoft.Bcl.Build, а файл packages.config находится рядом с файлом проекта.,

немного

Этот проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их. Дополнительные сведения см. на странице http://go.microsoft.com/fwlink/?LinkID=322105. . Отсутствует файл {путь к проекту}\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets.

и несколько ошибок CS0246, как и раньше.

Ошибки CS0234 больше нет.


person JamesFaix    schedule 08.07.2019    source источник
comment
Что значит не восстановлен? как ты проверял? (файл obj\project.assets.json должен быть сгенерирован), возникает ли ошибка сборки, если восстановление не выполняется вручную?   -  person Martin Ullrich    schedule 08.07.2019
comment
@MartinUllrich Обновлен раздел «Проблема» с дополнительными сведениями о сообщениях об ошибках.   -  person JamesFaix    schedule 08.07.2019
comment
Какую версию Visual Studio вы используете?   -  person baruchiro    schedule 09.07.2019
comment
Привет, каков результат, если вы создадите проект в командной строке? (Добавьте переключатель -restore в команду) И было бы лучше, если бы вы могли поделиться образцом с минимальной воспроизводимостью (пожалуйста, удалите в нем весь основной код и личные данные) .   -  person LoLance    schedule 09.07.2019
comment
@Барух VS 15.9.9   -  person JamesFaix    schedule 09.07.2019
comment
@Lance Li-MSFT смотрите обновления в конце поста   -  person JamesFaix    schedule 09.07.2019
comment
Извините, сейчас опубликовано   -  person JamesFaix    schedule 09.07.2019
comment
@JamesFaix Спасибо за воспроизводимый. Я проверю это позже и отвечу с обновлением как можно скорее.   -  person LoLance    schedule 09.07.2019
comment
@JamesFaix Вы уверены, что VS15 поддерживает netstandard?   -  person baruchiro    schedule 09.07.2019
comment
Да (VS15 = VS2017). У меня также установлен модуль .NET Core. Дата выпуска — март 2019 г. /примечания к выпуску/   -  person JamesFaix    schedule 09.07.2019
comment
Та же проблема, похоже, не воспроизводится на моей машине с вашим образцом, как вы сказали выше, он генерирует только CS0246. Для этого, согласно вашему образцу, в вашем образце существуют конфликты ссылок при нацеливании на v4.0. Такая же ситуация для вашего комплексного решения?   -  person LoLance    schedule 10.07.2019
comment
Любое обновление для этой проблемы? Ошибка Could not locate... связана с пакетом BCL. Попробуйте это обходное решение для устранения этой ошибки.   -  person LoLance    schedule 11.07.2019


Ответы (1)


Вы ссылаетесь на проект на основе PackageReference из классического файла csproj.

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

Чтобы обойти эту проблему, вы можете добавить следующее в <PropertyGroup> вашего классического файла csproj:

<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
person Martin Ullrich    schedule 09.07.2019