Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Управление зависимостями — это основная функция NuGet. Хотя управление зависимостями для одного проекта является простым, он становится все более сложным по мере роста числа проектов в решении.
Если вы управляете общими зависимостями для многих различных проектов, вы можете использовать функции центрального управления пакетами NuGet (CPM) для выполнения всех этих действий из одного центрального расположения.
Централизованное управление пакетами применяется ко всем <PackageReference>проектам MSBuild на основе (включая устаревшую версию CSPROJ).
Включение централизованного управления пакетами
Чтобы приступить к работе с центральным управлением пакетами, создайте Directory.Packages.props файл в корне репозитория и задайте для свойства MSBuild значение ManagePackageVersionsCentrallytrue.
Его можно создать вручную или использовать интерфейс командной строки .NET:
dotnet new packagesprops
Внутри Directory.Packages.propsопределите <PackageVersion /> элементы, чтобы указать идентификаторы пакетов и версии, используемые вашими проектами.
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="PackageA" Version="1.0.0" />
<PackageVersion Include="PackageB" Version="2.0.0" />
</ItemGroup>
</Project>
В каждом файле проекта определите <PackageReference /> элементы без атрибута Version .
Версия будет разрешена из соответствующей <PackageVersion /> записи.Directory.Packages.props
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PackageA" />
</ItemGroup>
</Project>
Теперь вы используете централизованное управление пакетами и управляете версиями в центральном расположении!
Правила централизованного управления пакетами
Файл Directory.Packages.props имеет определенные правила относительно его расположения и контекста в репозитории.
По умолчанию вычисляется только один Directory.Packages.props файл для заданного проекта.
Если в репозитории несколько Directory.Packages.props файлов, то для него будет вычисляться файл, ближайший к каталогу данного проекта.
Это обеспечивает дополнительный контроль на различных уровнях репозитория.
Рассмотрим следующую структуру каталогов репозитория:
📂 (root)
├─📄 Directory.Packages.props
|
├─📂Solution1
| ├─ 📄Directory.Packages.props
| |
| └─ 📂 Project1
| └─📄Project1.csproj
|
└─ 📂 Solution2
└─ 📂 Project2
└─ 📄 Project2.csproj
Project1.csproj будет использовать Directory.Packages.props файл в каталоге Repository\Solution1\ .
Если вы хотите включить параметры из родительского элемента Directory.Packages.props, необходимо импортировать его вручную.
<Project>
<Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Packages.props, $(MSBuildThisFileDirectory)..))" />
<ItemGroup>
<PackageVersion Update="Newtonsoft.Json" Version="12.0.1" />
</ItemGroup>
</Project>
Project2.csproj будет оценивать Directory.Packages.props файл в корневом каталоге.
Заметка
MSBuild автоматически импортирует первый Directory.Packages.props файл, который он находит в каталоге проекта или любом родительском каталоге.
При наличии нескольких таких файлов необходимо вручную импортировать родительские файлы по мере необходимости.
Начало работы
Чтобы полностью подключить репозиторий, выполните следующие действия.
- Создайте новый файл в корне репозитория с именем
Directory.Packages.props, который объявляет централизованно определенные версии пакетов и задает для свойства MSBuildManagePackageVersionsCentrallyзначениеtrue. - Объявите элементы
<PackageVersion />вDirectory.Packages.props. - Объявите в файлах проекта элементы
<PackageReference />без атрибутовVersion.
Пример того, как может выглядеть централизованное управление пакетами, см. в нашем репозитории примеров.
Использование разных версий для разных целевых платформ
По мере развития пакетов NuGet владельцы пакетов могут отказаться от поддержки старых целевых платформ. Это может привести к проблемам для разработчиков библиотек, которые по-прежнему предназначены для более старых платформ, но хотят ссылаться на более новые версии пакетов для более новых целевых платформ.
Например, если проект предназначен для .NET Standard 2.0, .NET 8.0 и .NET Framework 4.7.2, но PackageA больше не поддерживает .NET Standard 2.0 в последней версии, можно указать разные версии для каждой целевой платформы.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net8.0;net472</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PackageA" />
</ItemGroup>
</Project>
В этом случае определите разные версии для каждой целевой платформы в условиях Directory.Packages.propsMSBuild:
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="PackageA" Version="1.0.0" Condition="'$(TargetFramework)' == 'netstandard2.0'" />
<PackageVersion Include="PackageA" Version="2.0.0" Condition="'$(TargetFramework)' == 'net8.0' Or '$(TargetFramework)' == 'net472'" />
</ItemGroup>
</Project>
Транзитивное закрепление
Вы можете автоматически переопределить транзитивную версию пакета без явного элемента верхнего уровня <PackageReference /> , выбрав функцию, известную как транзитивное закрепление.
Это повышает транзитивную зависимость до зависимости верхнего уровня от вашего имени, когда это необходимо.
Обратите внимание, что понижение не допускается при транзитивном закреплении пакета. Если вы пытаетесь закрепить пакет до более низкой версии, чем запрошенная зависимостями, восстановление вызовет ошибку NU1109.
Эту функцию можно включить, задав свойство MSBuild CentralPackageTransitivePinningEnabledtrue в проекте или в файле импорта Directory.Packages.props или Directory.Build.props:
<PropertyGroup>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>
Транзитивное закрепление и пакет
При транзитивном закреплении пакета проект использует более высокую версию, чем запрошенную зависимостями. Если вы создадите пакет из проекта, чтобы убедиться, что пакет будет работать, NuGet будет продвигать транзитивно закрепленные зависимости до явных зависимостей в nuspec.
В следующем примере PackageA 1.0.0 имеет зависимость от PackageB 1.0.0.
<Project>
<ItemGroup>
<PackageVersion Include="PackageA" Version="1.0.0" />
<PackageVersion Include="PackageB" Version="2.0.0" />
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PackageA" />
</ItemGroup>
</Project>
При использовании команды пакета для создания пакета оба пакета будут отображаться в группе зависимостей.
<group targetFramework="net6.0">
<dependency id="PackageA" version="1.0.0" exclude="Build,Analyzers" />
<dependency id="PackageB" version="2.0.0" exclude="Build,Analyzers" />
</group>
Из-за этого следует тщательно оценить использование транзитивного закрепления при создании библиотеки, так как это может привести к зависимостям, которые вы не ожидали.
Переопределение версий пакетов
Вы можете переопределить отдельную версию пакета с помощью свойства VersionOverride в элементе <PackageReference />.
Это будет иметь приоритет над любым центральным определением <PackageVersion />.
<Project>
<ItemGroup>
<PackageVersion Include="PackageA" Version="1.0.0" />
<PackageVersion Include="PackageB" Version="2.0.0" />
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PackageA" VersionOverride="3.0.0" />
</ItemGroup>
</Project>
Эту функцию можно отключить, задав свойство MSBuild CentralPackageVersionOverrideEnabledfalse в проекте или в файле импорта Directory.Packages.props или Directory.Build.props.
<PropertyGroup>
<CentralPackageVersionOverrideEnabled>false</CentralPackageVersionOverrideEnabled>
</PropertyGroup>
Если эта функция отключена, указание VersionOverride для любого элемента <PackageReference /> приведет к ошибке во время восстановления, указывая, что эта функция отключена.
Отключение централизованного управления пакетами
Чтобы отключить централизованное управление пакетами для определенного проекта, задайте для свойства MSBuild значение ManagePackageVersionsCentrallyfalse:
<PropertyGroup>
<ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
</PropertyGroup>
Глобальные ссылки на пакеты
Заметка
Эта функция доступна только в Visual Studio 2022 17.4 или более поздней версии, пакет SDK для .NET 7.0.100.preview7 или более поздней версии, а также NuGet 6.4 или более поздней версии.
Глобальная ссылка на пакет используется для указания того, что пакет будет использоваться каждым проектом в репозитории. К ним относятся пакеты, которые выполняют управление версиями, расширяют сборку или другие пакеты, необходимые для всех проектов. Глобальные ссылки на пакеты добавляются в группу элементов PackageReference со следующими метаданными:
IncludeAssets="Runtime;Build;Native;contentFiles;Analyzers"
Это гарантирует, что пакет используется только в качестве зависимости разработки и предотвращает его включение в качестве ссылки на сборку во время компиляции.PrivateAssets="All"
Это предотвращает использование глобальных ссылок пакетов подчиненными зависимостями.
Элементы GlobalPackageReference должны размещаться в вашем Directory.Packages.props, чтобы их мог использовать каждый проект в репозитории.
<Project>
<ItemGroup>
<GlobalPackageReference Include="Nerdbank.GitVersioning" Version="3.5.109" />
</ItemGroup>
</Project>
Предупреждение NU1507 при использовании нескольких источников пакетов
При использовании централизованного управления пакетами NuGet регистрирует NU1507 предупреждение, если в конфигурации определено несколько источников пакетов.
Чтобы устранить это предупреждение, сопоставите источники пакетов с сопоставлением источников пакетов или укажите один источник пакета.
There are 3 package sources defined in your configuration. When using Central Package Management, please map your package sources with package source mapping (https://aka.ms/nuget-package-source-mapping) or specify a single package source.