Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Ссылки на пакеты, использующие элементы MSBuild
PackageReference также позволяет использовать условия MSBuild для выбора ссылок на пакеты в соответствии с целевой платформой и другими признаками. Он также обеспечивает детальный контроль над зависимостями и потоком содержимого. (Дополнительные сведения см. в разделе "Пакет NuGet" и восстановление в качестве целевых объектов MSBuild.)
Поддержка типов проектов
По умолчанию PackageReference используется для проектов .NET, проектов .NET Standard и проектов UWP, предназначенных для Windows 10 сборки 15063 (Creators Update) и более поздних версий, за исключением проектов UWP C++. Проекты .NET Framework поддерживают PackageReference, но сейчас по умолчанию используют packages.config. Чтобы использовать PackageReference в проекте .NET Framework, перенесите зависимости из packages.config файла проекта, а затем удалите packages.config.
ASP.NET приложения, предназначенные для полной платформы .NET Framework, включают только ограниченную поддержку PackageReference. Типы проектов C++и JavaScript не поддерживаются.
Добавление PackageReference
Добавьте зависимость в файл проекта, используя следующий синтаксис:
<ItemGroup>
<!-- ... -->
<PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0" />
<!-- ... -->
</ItemGroup>
Управление версией зависимости
При указании версии пакета действует то же соглашение, что и при использовании packages.config.
<ItemGroup>
<!-- ... -->
<PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0" />
<!-- ... -->
</ItemGroup>
В приведенном выше примере 3.6.0 означает любую версию, которая имеет >значение =3.6.0 с предпочтением самой низкой версии, как описано в разделе "Управление версиями пакетов".
Использование PackageReference для проекта без зависимостей пакета
Дополнительно: если в проекте нет установленных пакетов (нет объектов PackageReference в файле, а также файла packages.config), но вы хотите восстанавливать проект в стиле PackageReference, можно задать для свойства RestoreProjectStyle проекта значение PackageReference в файле проекта.
<PropertyGroup>
<!--- ... -->
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
<!--- ... -->
</PropertyGroup>
Это может быть полезно, если вы ссылаетесь на проекты в стиле PackageReference, такие как существующие проекты csproj или в стиле SDK. Это позволит вашему проекту транзитивно ссылаться на пакеты, на которые ссылаются эти проекты.
PackageReference и источники
В проектах PackageReference транзитивные версии зависимостей определяются во время восстановления. Таким образом, в проектах PackageReference все источники должны быть доступны для всех восстановлений.
Плавающие версии
Плавающие версии можно использовать с PackageReference:
<ItemGroup>
<!-- ... -->
<PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.*" />
<PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0-beta.*" />
<!-- ... -->
</ItemGroup>
Управление ресурсами зависимости
Зависимость может применяться исключительно для удобства разработки. В этом случае доступ к ней не нужно предоставлять проектам, использующим пакет. Для управления данным поведением можно использовать метаданные PrivateAssets.
<ItemGroup>
<!-- ... -->
<PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<!-- ... -->
</ItemGroup>
Ниже перечислены теги метаданных, управляющие ресурсами зависимостей.
| Tag | Description | Значение по умолчанию |
|---|---|---|
| IncludeAssets | Эти ресурсы будут израсходованы. | all |
| ExcludeAssets | Эти ресурсы не будут использоваться. | none |
| PrivateAssets | Эти ресурсы будут использоваться, но не будут передаваться в родительский проект. | contentfiles;analyzers;build |
Допустимые значения для этих тегов приведены следующим образом: несколько значений, разделенных точкой с запятой, за исключением all и noneкоторые должны отображаться сами по себе:
| Value | Description |
|---|---|
| compile | Содержимое папки lib и контролирует возможность компиляции вашего проекта с использованием сборок в этой папке |
| runtime | Содержимое папок lib и runtimes и определяет, будут ли эти сборки скопированы в выходной каталог сборки. |
| contentFiles | Содержимое папки contentfiles |
| build |
.props и .targets в папке build |
| buildMultitargeting | Файлы .props и .targets в папке buildMultitargeting (4.0) для кросс-фреймворк нацеливания. |
| buildTransitive | Файлы .props(5.0+) и .targets в папке buildTransitive для ресурсов, которые можно транзитивно передавать в любой потребляющий проект. См. страницу функции. |
| analyzers | Анализаторы .NET |
| native | Содержимое папки native |
| none | Никакие из перечисленных выше ресурсов не используются. |
| all | Все перечисленные выше (кроме none) |
<ItemGroup>
<!-- ... -->
<!-- Everything except the content files will be consumed by the project -->
<!-- Everything except content files and analyzers will flow to the parent project-->
<PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0">
<IncludeAssets>all</IncludeAssets> <!-- Default is `all`, can be omitted-->
<ExcludeAssets>contentFiles</ExcludeAssets>
<PrivateAssets>contentFiles;analyzers</PrivateAssets>
</PackageReference>
<!-- ... -->
<!-- Everything except the compile will be consumed by the project -->
<!-- Everything except contentFiles will flow to the parent project-->
<PackageReference Include="Contoso.Utility.SomeOtherUsefulStuff" Version="3.6.0">
<ExcludeAssets>compile</ExcludeAssets>
<PrivateAssets>contentFiles</PrivateAssets>
</PackageReference>
<!-- ... -->
</ItemGroup>
Обратите внимание: так как build не включен в PrivateAssets, цели и свойства будут передаваться в родительский проект. Предположим, что приведенная выше ссылка используется в проекте, в рамках которого выполняется сборка пакета NuGet с именем AppLogger. Пакет AppLogger может использовать цели и свойства из Contoso.Utility.UsefulStuff, а также проекты, использующие AppLogger.
Note
Когда для developmentDependency в файле .nuspec задано значение true, это указывает на то, что пакет помечен как зависимость только для разработки, что позволяет запретить его включение в качестве зависимости в другие пакеты. При использовании PackageReference (NuGet 4.8+) этот флажок также означает, что ресурсы времени компиляции будут исключаться из процесса компиляции. Дополнительные сведения см. в статье Поддержка DevelopmentDependency для PackageReference.
Добавление условия PackageReference
Условие можно использовать для управления включением пакета. Условия могут использовать любую переменную MSBuild или переменную, определенную в целевом или props-файле. Однако в настоящее время поддерживается только TargetFramework переменная.
Например, предположим, что вы нацелены на netstandard1.4 и net452, и имеете зависимость, которая применима только для net452. В этом случае вы не хотите, netstandard1.4 чтобы проект, используюющий пакет, добавлял эту ненужную зависимость. Чтобы предотвратить это, укажите условие для PackageReference следующим образом:
<ItemGroup>
<!-- ... -->
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" Condition="'$(TargetFramework)' == 'net452'" />
<!-- ... -->
</ItemGroup>
При сборке пакета с использованием этого проекта Newtonsoft.Json будет отображаться как зависимость, включенная только для net452.
Результат применения условия к PackageReference в Visual Studio 2017
Условия также могут применяться на уровне ItemGroup, и они будут применяться ко всем дочерним элементам PackageReference.
<ItemGroup Condition = "'$(TargetFramework)' == 'net452'">
<!-- ... -->
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
<PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0" />
<!-- ... -->
</ItemGroup>
GeneratePathProperty
Эта функция доступна в NuGet 5.0 или более поздней версии и в Visual Studio 2019 16.0 или более поздней версии.
Иногда требуется ссылаться на файлы в пакете из целевого объекта MSBuild.
В проектах на основе packages.config пакеты устанавливаются в папку, расположенную относительно файла проекта. Однако в PackageReference пакеты используются из папки "global-packages", которая может различаться на разных компьютерах.
Чтобы устранить эту проблему, NuGet предоставляет свойство, указывающее на расположение, из которого будет использоваться пакет.
Example:
<ItemGroup>
<PackageReference Include="Some.Package" Version="1.0.0" GeneratePathProperty="true" />
</ItemGroup>
<Target Name="TakeAction" AfterTargets="Build">
<Exec Command="$(PkgSome_Package)\something.exe" />
</Target>
Кроме того, NuGet автоматически создает свойства для пакетов, содержащих папку инструментов.
<ItemGroup>
<PackageReference Include="Package.With.Tools" Version="1.0.0" />
</ItemGroup>
<Target Name="TakeAction" AfterTargets="Build">
<Exec Command="$(PkgPackage_With_Tools)\tools\tool.exe" />
</Target>
Свойства MSBuild и идентификаторы пакетов не имеют одинаковых ограничений, поэтому идентификатор пакета необходимо изменить на имя, дружелюбное к MSBuild, с префиксом в виде слова Pkg.
Чтобы проверить точное имя созданного свойства, обратитесь к созданному файлу nuget.g.props.
Псевдонимы PackageReference
В некоторых редких случаях разные пакеты будут содержать классы в одном пространстве имен. Начиная с версии 5.7 для NuGet и обновления 7 для Visual Studio 2019, поддержка PackageReference аналогична поддержке ProjectReference и включает в себя псевдонимы. По умолчанию псевдонимы не предоставляются. При указании псевдонима все сборки, поступающие из аннотированного пакета, должны ссылаться на псевдоним.
Пример использования можно просмотреть в NuGet\Samples.
В файле проекта псевдонимы указываются следующим образом:
<ItemGroup>
<PackageReference Include="NuGet.Versioning" Version="5.8.0" Aliases="ExampleAlias" />
</ItemGroup>
И в коде используйте его следующим образом:
extern alias ExampleAlias;
namespace PackageReferenceAliasesExample
{
...
{
var version = ExampleAlias.NuGet.Versioning.NuGetVersion.Parse("5.0.0");
Console.WriteLine($"Version : {version}");
}
...
}
Предупреждения и ошибки NuGet
Эта функция доступна в NuGet 4.3 или более поздней версии и в Visual Studio 2017 15.3 или более поздней версии.
Для многих сценариев упаковки и восстановления все предупреждения и ошибки NuGet имеют код, который начинается на NU****. Все предупреждения и ошибки NuGet перечислены в справочной документации.
NuGet следит за следующими свойствами предупреждения:
-
TreatWarningsAsErrors, обрабатывайте все предупреждения как ошибки. -
WarningsAsErrors, обрабатывайте определенные предупреждения как ошибки. -
NoWarn, скрывать определенные предупреждения на уровне проекта или пакета.
Examples:
<PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
...
<PropertyGroup>
<WarningsAsErrors>$(WarningsAsErrors);NU1603;NU1605</WarningsAsErrors>
</PropertyGroup>
...
<PropertyGroup>
<NoWarn>$(NoWarn);NU5124</NoWarn>
</PropertyGroup>
...
<ItemGroup>
<PackageReference Include="Contoso.Package" Version="1.0.0" NoWarn="NU1605" />
</ItemGroup>
Подавление предупреждений NuGet
Хотя рекомендуется устранять все предупреждения NuGet во время операций упаковки и восстановления, в некоторых случаях оправдано их подавление. Чтобы подавить предупреждение в масштабе проекта, рекомендуется сделать следующее:
<PropertyGroup>
<PackageVersion>5.0.0</PackageVersion>
<NoWarn>$(NoWarn);NU5104</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Contoso.Package" Version="1.0.0-beta.1"/>
</ItemGroup>
Иногда предупреждения применяются только к определенному пакету в графе. Вы можете более выборочно подавить это предупреждение, добавив элемент NoWarn в PackageReference.
<PropertyGroup>
<PackageVersion>5.0.0</PackageVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Contoso.Package" Version="1.0.0-beta.1" NoWarn="NU1603" />
</ItemGroup>
Подавление предупреждений пакета NuGet в Visual Studio
В Visual Studio можно также подавлять предупреждения через среду разработки.
Блокировка зависимостей
Эта функция доступна в NuGet 4.9 или более поздней версии и в Visual Studio 2017 15.9 или более поздней версии.
Входные данные для восстановления в NuGet — это набор элементов PackageReference из файла проекта (зависимости верхнего уровня или прямые зависимости), а выходные данные — это полное замыкание всех зависимостей пакета, включая транзитивные зависимости. NuGet всегда пытается создать одно и то же полное замыкание зависимостей пакета, если входной список PackageReference не был изменен. Но в некоторых случаях это нельзя осуществить. Рассмотрим пример.
При использовании плавающих версий, таких как ``. При каждом восстановлении пакетов предполагается перейти к последней версии. Но иногда пользователям требуется, чтобы граф был закреплен за определенной последней версией, а переход к более поздней версии, если она доступна, происходил при явном указании.
Опубликована более новая версия пакета, соответствующая требованиям к версии PackageReference. Рассмотрим пример.
День 1. Если вы указали
<PackageReference Include="My.Sample.Lib" Version="4.0.0"/>, но версии, доступные в репозиториях NuGet, были 4.1.0, 4.2.0 и 4.3.0. В этом случае версия NuGet была бы определена на 4.1.0 (ближайшая минимальная версия).День 2. Публикуется версия 4.0.0. Теперь NuGet найдет точное соответствие и начнет процесс разрешения с версии 4.0.0.
Указанная версия пакета будет удалена из репозитория. Хотя на сайте nuget.org нельзя удалять пакеты, не все репозитории пакетов имеют такие ограничения. В результате этого в NuGet выполняется поиск наилучшего соответствия, если не удается разрешить до удаленной версии.
Включение функции файла блокировки
Чтобы сохранить полное закрытие зависимостей пакета, вы можете отказаться от функции файла блокировки, задав свойство RestorePackagesWithLockFile MSBuild для проекта:
<PropertyGroup>
<!--- ... -->
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<!--- ... -->
</PropertyGroup>
Если это свойство задано, восстановление NuGet создаст файл блокировки (packages.lock.json) в корневом каталоге проекта, который перечисляет все зависимости пакета.
Note
Как только в корневом каталоге проекта есть packages.lock.json файл, файл блокировки всегда используется при восстановлении, даже если свойство RestorePackagesWithLockFile не задано. Еще один способ включить эту функцию — создать пустой файл packages.lock.json в корневом каталоге проекта.
Поведение с файлом блокировки
Если файл блокировки присутствует для проекта, NuGet использует этот файл блокировки для запуска restore. NuGet выполняет быструю проверку, чтобы узнать, были ли изменения в зависимостях пакета, как упоминалось в файле проекта (или зависимых файлах проектов), и если изменения не были, он просто восстанавливает пакеты, упомянутые в файле блокировки. Повторная проверка зависимостей пакета не выполняется.
Если NuGet обнаруживает изменения в зависимостях, определенных в файлах проекта, он повторно оценивает граф пакетов и обновляет файл блокировки, чтобы отразить новое закрытие пакета для проекта.
В ситуациях CI/CD и других случаях, когда вы не хотите изменять зависимости пакета на лету, вы можете сделать это, установив для lockedmode значение true:
Для dotnet.exe выполните следующую команду:
> dotnet.exe restore --locked-mode
Для msbuild.exe выполните такую команду:
> msbuild.exe -t:restore -p:RestoreLockedMode=true
Вы также можете задать это условное свойство MSBuild в файле проекта:
<PropertyGroup>
<!--- ... -->
<RestoreLockedMode>true</RestoreLockedMode>
<!--- ... -->
</PropertyGroup>
Если режим блокировки указан как true, то будут восстановлены пакеты, перечисленные в файле блокировки, либо восстановление завершится ошибкой, если вы обновили определенные зависимости пакетов для проекта после создания файла блокировки.
Блокировка файлов и PrunePackageReference
PrunePackageReference изменяет зависимости проекта, удаляя ненужные транзитивные пакеты. При удалении этих пакетов это не должно оказывать влияния на среду выполнения, но повлияет только на файлы блокировки. Если вы включите очистку для существующего проекта, повторное создание файла блокировки может привести к уменьшению числа пакетов по сравнению с состоянием до очистки. Файл блокировки, проверка актуальности которого поддерживает режим блокировки, учитывает обрезку. Это означает, что если вы включили обрезку в проекте, эта проверка будет учитывать удаления пакетов. Однако при следующем повторном создании файла блокировки он исключит обрезаемые пакеты, поэтому вы можете увидеть дифф, который больше обычного.
Добавление файла блокировки в исходный репозиторий
Если вы создаете приложение или исполняемый файл, и проект находится в начале цепочки зависимостей, зафиксируйте файл блокировки в репозитории исходного кода, чтобы NuGet мог использовать его во время восстановления.
Однако если ваш проект является проектом библиотеки, который не распространяется, или проектом общего кода, от которого зависят другие проекты, не следует включать файл блокировки в состав исходного кода. Нет никакого вреда в сохранении файла блокировки, но зависимости пакетов для общего проекта кода, указанные в файле блокировки, нельзя использовать во время восстановления или сборки проекта, зависящего от этого общего проекта кода.
Example:
ProjectA
|------> PackageX 2.0.0
|------> ProjectB
|------>PackageX 1.0.0
Если ProjectA имеет зависимость от версии PackageX2.0.0 и также ссылается на ProjectB, который зависит от версии PackageX1.0.0, то файл блокировки для ProjectB будет содержать зависимость от версии PackageX1.0.0. Однако, при создании ProjectA его файл блокировки будет содержать зависимость от PackageX версии 2.0.0, а не1.0.0, как указано в файле блокировки для ProjectB. Таким образом, файл блокировки проекта общего кода играет незначительную роль для разрешенных пакетов, от которых зависят проекты.
Расширяемость файла блокировки
Вы можете управлять различным поведением восстановления с использованием файла блокировки, как описано ниже.
| параметр NuGet.exe | Параметр dotnet | Вариант, аналогичный использованию MSBuild | Description |
|---|---|---|---|
-UseLockFile |
--use-lock-file |
RestorePackagesWithLockFile | Разрешение использовать файл блокировки. |
-LockedMode |
--locked-mode |
RestoreLockedMode | Включение режима блокировки для восстановления. Это полезно в сценариях CI/CD, когда нужно реализовать воспроизводимые сборки. |
-ForceEvaluate |
--force-evaluate |
RestoreForceEvaluate | Этот параметр удобно использовать с пакетами с гибкими версиями, определенными в проекте. По умолчанию в NuGet версия пакета не обновляется автоматически после каждого восстановления, если вы не запустили восстановление с этим параметром. |
-LockFilePath |
--lock-file-path |
NuGetLockFilePath | Установка пользовательского расположения файла блокировки для проекта. По умолчанию NuGet поддерживает packages.lock.json в корневом каталоге. Если у вас несколько проектов в одном каталоге, NuGet поддерживает использование файлов блокировки, специфичных для проекта. |
Разрешатель зависимостей NuGet
Сопоставитель зависимостей NuGet следует четырем правилам, как описано в документе разрешения зависимостей.
Чтобы повысить производительность и масштабируемость операции восстановления, алгоритм восстановления был перезаписан в выпуске 6.12.
По состоянию на выпуск 6.12 новый алгоритм восстановления включен по умолчанию для всех проектов PackageReference.
Хотя новый алгоритм восстановления функционально эквивалентен предыдущему, как и в любом программном обеспечении, возможны ошибки.
Чтобы вернуться к предыдущей реализации, установите свойство MSBuild RestoreUseLegacyDependencyResolver в true.
Если вы столкнулись с сбоями восстановления в версиях 6.12, .NET 9 или 17.12, которые не встречались в более ранних версиях, зарегистрируйте проблему на сайте GitHub. Любые различия между старыми и новыми алгоритмами могут иметь различные последствия, например во время компиляции или во время выполнения. Есть также вероятность того, что изменения не приводят к сбоям, а к восстановлению различных версий пакетов. Если вы считаете, что вы можете повлиять на любые изменения, ниже приведены шаги, которые можно предпринять, чтобы проверить, являются ли изменения в алгоритме восстановления NuGet первопричиной.
Восстановление записывает свои результаты в каталог MSBuildProjectExtensionsPath, который можно сравнить с новыми и старыми алгоритмами для поиска различий.
Обычно это папка obj вашей сборки.
Вы можете использовать msbuild.exe или dotnet.exe для выполнения следующих шагов.
Удалите папку
objдля вашего проекта.Запустить
msbuild -t:restoreСохраните содержимое
objв местоположение, указывая, что это поведениеnew.Выполните
msbuild -t:restore -p:RestoreUseLegacyDependencyResolver="true".Сохраните содержимое
objв местоположение, указывающее на то, что этоlegacyповедение.Сравните файлы в двух каталогах, особенно project.assets.json.
Средства, которые могут выделить различия, особенно полезны для этого (например, в Visual Studio Code, откройте оба файла и используйте правой кнопкой мыши пункт "Выбрать для сравнения" и "сравнить с выбранным").
При выполнении приведенного выше метода должно быть ровно одно отличие между файлами project.assets.json.
"projectStyle": "PackageReference",
+ "restoreUseLegacyDependencyResolver": true,
"fallbackFolders": [
Если есть еще различия, создайте задачу на GitHub со всеми сведениями.
AssetTargetFallback
Свойство AssetTargetFallback позволяет указать дополнительные совместимые версии платформы для проектов, на которые ссылается ваш проект, и пакетов NuGet, используемых вашим проектом.
Если вы указали зависимость пакета с помощью PackageReference, но этот пакет не содержит активов, совместимых с целевой платформой вашего проекта, тогда в игру вступает свойство AssetTargetFallback. Совместимость пакета, на который указывает ссылка, повторно проверяется с помощью каждого целевого фреймворка, указанного в AssetTargetFallback.
При ссылке на project или на package через AssetTargetFallback будет выдано предупреждение NU1701.
Примеры того, как AssetTargetFallback влияет на совместимость, приводятся в таблице ниже.
| Проектная рамка | AssetTargetFallback | Платформы пакетов | Result |
|---|---|---|---|
| .NET Framework 4.7.2. | .NET Standard 2.0 | .NET Standard 2.0 | |
| .NET Core App 3.1 | .NET Standard 2.0, .NET Framework 4.7.2 | .NET Standard 2.0 | |
| .NET Core App 3.1 | .NET Framework 4.7.2. | Несовместимо, ошибка с кодом NU1202 | |
| .NET Core App 3.1 | net472;net471 | .NET Framework 4.7.2. | .NET Framework 4.7.2 с NU1701 |
Можно указать несколько фреймворков, используя ; в качестве разделителя. Чтобы добавить резервную платформу, можно выполнить следующие действия:
<AssetTargetFallback Condition=" '$(TargetFramework)'=='netcoreapp3.1' ">
$(AssetTargetFallback);net472;net471
</AssetTargetFallback>
Вы можете опустить $(AssetTargetFallback), если хотите перезаписать, вместо того чтобы добавлять к существующим значениям AssetTargetFallback.
Note
Если вы используете проект на основе .NET SDK, соответствующие параметры уже настроены, и задавать их вручную не требуется.
Ранее для устранения этой проблемы использовалась функция $(PackageTargetFallback), которая по своей сути не работает и не должна использоваться. Чтобы перейти с $(PackageTargetFallback) на $(AssetTargetFallback), просто измените имя свойства.
PrunePackageReference
Среда выполнения .NET постоянно развивается: с каждым релизом она получает улучшения производительности и новые API.
Новые функции, добавленные в .NET, также иногда предоставляются в виде пакетов, чтобы разработчики, использующие старые целевые платформы, могли использовать библиотеку, например System.Text.Json.
Это часто может привести к System.Text.Json 8.0.0 в проекте, нацеленном на .NET 9 или .NET 8. Эта зависимость не требуется, и разрешение конфликтов сборки не будет использовать сборку, полученную из пакета, так как она уже доступна в среде выполнения .NET.
Начиная с NuGet версии 6.13 и пакета SDK для .NET 9.0.200, PrunePackageReference позволяет выполнять очистку этих пакетов во время восстановления для проектов на основе пакета SDK для .NET.
Первая итерация обрезки затрагивала только транзитивные пакеты, но начиная с .NET SDK 10, обрезка пакетов затрагивает также прямые пакеты.
Обрезка пакетов доступна как функция, которую можно включить по желанию, в SDK .NET 9 и включена по умолчанию для всех фреймворков проекта, который нацелен на >= .NET 10.0, в SDK .NET 10.
Обрезка пакетов доступна только с помощью резольвера зависимостей по умолчанию, начиная с версии 6.12, когда выпущено в.
Спецификация PrunePackageReference
Список пакетов, подлежащих удалению, определяется пунктом PrunePackageReference.
| Attributes | Description |
|---|---|
| Version | Указывает максимальную версию для удаления.
1.0.0 означает, что все пакеты до 1.0.0 будут удалены. Для 1.0.00.9.0 и 1.0.0 будут удалены, но 1.0.1 останется. |
Следующие свойства можно использовать для изменения поведения обрезки.
| PropertyName | Description |
|---|---|
| RestoreEnablePackagePruning | Включает очистку пакетов для пакетов, указанных с PrunePackageReference. Это свойство соответствует целевой платформе, а допустимые значения — true и false. Значения по умолчанию могут отличаться в зависимости от пакета SDK для .NET, как описано выше. |
.NET SDK заранее определяет, какие пакеты следует удалить за вас. Этот список основан на общих платформах, указанных в проекте. Рассматриваются только прямые ссылки на фреймворки, и данные обрезки не добавляются для фреймворков, которые подключаются через пакеты.
Как работает PrunePackageReference
Если указано, что пакет должен быть удалён во время восстановления, он удаляется из графа зависимостей. При удалении пакета сообщается, что пакет удален для данной целевой платформы, если включена подробная детализация.
Для транзитивных пакетов, то есть зависимости других пакетов или проектов, пакеты не загружаются и не отображаются ни в одном из выходных данных NuGet.
Для прямых пакетов PrivateAssets='all' и IncludeAssets='none' неявно применяются.
-
IncludeAssets='none'гарантирует, что сборки из этого пакета не используются во время сборки. До появления процесса сокращения, разрешение конфликтов во время сборки обеспечивало, что сборки платформы предпочитались перед теми, которые поступали из пакетов. -
PrivateAssets='all'гарантирует, что пакеты не включаются в сборки или через ссылки на проекты.
Example:
Проект, как показано ниже:
<PropertyGroup>
<TargetFrameworks>net9.0;netstandard2.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Text.Json" Version="9.0.4" />
</ItemGroup>
будет иметь nuspec со следующими зависимостями:
<dependencies>
<group targetFramework=".NETFramework4.7.2">
<dependency id="System.Text.Json" version="9.0.4" />
</group>
<group targetFramework="net9.0">
</group>
</dependencies>
Если прямая функция PackageReference может быть полностью удалена из проекта, а одна из платформ проектов — .NET 10 или более поздней версии, nu1510 будет вызвана запросом на удаление пакета. После этого предложения будет снижена сложность графа проекта.
В следующей таблице перечислены все поведение обрезки пакета.
| Ликвидация зависимостей | Behavior |
|---|---|
| Соответствует идентификатору транзитивного пакета, поступающего через другой пакет | Prune |
| Соответствует идентификатору транзитивного пакета, поступающего через другой проект | Prune |
Соответствует идентификатору элемента PackageReference |
Примените PrivateAssets='all' и IncludeAssets='none' вызовите предупреждение NU1510 , когда пакет можно удалить из всех платформ и проект предназначен для .NET 10. |
Соответствует идентификатору ProjectReference |
Не обрезайте и не создавайте предупреждение NU1511 , когда проект предназначен для .NET 10 |
Приложения PrunePackageReference
Преимущества обрезки пакета двоякие:
- Преимущества производительности благодаря сокращению количества пакетов в графе зависимостей
- Уменьшение ложноположительных срабатываний сканерами компонентов, такими как
NuGetAudit
Обрезка особенно важна при аудите пакетов с установленным NuGetAuditMode значением all. Если вы используете .NET 9, рекомендуется попробовать обрезку, установив для этого значение RestoreEnablePackagePruningtrue.