Gestion centralisée des packages (CPM)
La gestion des dépendances est une fonctionnalité essentielle de NuGet. La gestion des dépendances pour un seul projet peut être facile. La gestion des dépendances pour les solutions multi-projets peut s’avérer difficile à mesure qu’elles commencent à s’adapter à la taille et à la complexité. Dans les situations où vous gérez les dépendances courantes pour de nombreux projets différents, vous pouvez tirer parti des fonctionnalités de gestion centralisée des packages (CPM) nuGet pour ce faire à partir de la facilité d’un emplacement unique.
Historiquement, les dépendances de package NuGet ont été gérées à l’un des deux emplacements suivants :
-
packages.config
: fichier XML utilisé dans les types de projet plus anciens pour conserver la liste des packages référencés par le projet. -
<PackageReference />
- Un élément XML utilisé dans les projets MSBuild définit les dépendances de package NuGet.
À partir de NuGet 6.2, vous pouvez gérer de manière centralisée vos dépendances dans vos projets avec l’ajout d’un fichier Directory.Packages.props
et d’une propriété MSBuild.
La fonctionnalité est disponible dans tous les outils intégrés NuGet, en commençant par les versions suivantes.
Les outils plus anciens ignorent les configurations et fonctionnalités de gestion centralisée des packages. Pour utiliser cette fonctionnalité dans la mesure la plus complète, assurez-vous que tous vos environnements de build utilisent les dernières versions d’outils compatibles.
La gestion centralisée des packages s’applique à tous les projets MSBuild basés sur <PackageReference>
(y compris l’ancienneCSPROJ) tant que les outils compatibles sont utilisés.
Activation de la gestion centralisée des packages
Pour commencer à gérer les packages centraux, vous devez créer un fichier Directory.Packages.props
à la racine de votre référentiel et définir la propriété MSBuild ManagePackageVersionsCentrally
sur true
.
Vous pouvez le créer manuellement ou utiliser l’interface CLI dotnet :
dotnet new packagesprops
À l’intérieur, vous définissez ensuite chacune des versions de paquet requises pour vos projets en utilisant des éléments <PackageVersion />
qui définissent l’ID de paquet et la version.
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
</Project>
Pour chaque projet, vous définissez ensuite une <PackageReference />
mais omettez l’attribut Version
, car la version sera atteinte à partir d’un élément de <PackageVersion />
correspondant.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" />
</ItemGroup>
</Project>
Vous utilisez maintenant la gestion centralisée des packages et la gestion de vos versions dans un emplacement central !
Règles de gestion centralisée des packages
Le fichier Directory.Packages.props
a plusieurs règles en ce qui concerne l’emplacement où il se trouve dans le répertoire d’un référentiel et son contexte. Par souci de simplicité, un seul fichier Directory.Packages.props
est évalué pour un projet donné.
Cela signifie que si vous aviez plusieurs fichiers Directory.Packages.props
dans votre référentiel, le fichier le plus proche du répertoire de votre projet sera évalué pour celui-ci. Cela vous permet d’effectuer un contrôle supplémentaire à différents niveaux de votre référentiel.
Voici un exemple, considérez la structure de référentiel suivante :
Repository
|-- Directory.Packages.props
|-- Solution1
|-- Directory.Packages.props
|-- Project1
|-- Solution2
|-- Project2
- Project1 évalue le fichier
Directory.Packages.props
dans le répertoireRepository\Solution1\
et doit importer manuellement le fichier suivant si vous le souhaitez.<Project> <Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Packages.props, $(MSBuildThisFileDirectory)..))" /> <ItemGroup> <PackageVersion Update="Newtonsoft.Json" Version="12.0.1" /> </ItemGroup> </Project>
- Project2 évalue le fichier
Directory.Packages.props
dans le répertoireRepository\
.
Remarque : MSBuild n’importe pas automatiquement chaque Directory.Packages.props
pour vous, seulement le premier le plus proche du projet. Si vous avez plusieurs Directory.Packages.props
, vous devez importer manuellement le parent, tandis que la racine Directory.Packages.props
ne nécessite pas d'être importée.
Démarrer
Pour intégrer entièrement votre référentiel, procédez comme suit :
- Créez un fichier à la racine de votre référentiel nommé
Directory.Packages.props
qui déclare vos versions de package définies de manière centralisée et définissez la propriété MSBuildManagePackageVersionsCentrally
surtrue
. - Déclarez
<PackageVersion />
éléments dans votreDirectory.Packages.props
. - Déclarez les éléments
<PackageReference />
sans attributsVersion
dans vos fichiers de projet.
Pour une idée de comment la gestion centralisée des paquets pourrait se présenter, reportez-vous à notre dépôt d'exemples .
Épinglage transitif
Vous pouvez automatiquement remplacer une version de package transitive, même sans un <PackageReference />
explicite de niveau supérieur, en choisissant une fonctionnalité appelée épinglage transitif. Cela favorise une dépendance transitive vers une dépendance de niveau supérieur implicitement en votre nom si nécessaire.
Notez que les rétrogradations sont autorisées lors de l’épinglage transitif d’un package. Si vous tentez d’épingler un package à une version inférieure à celle demandée par vos dépendances, la restauration déclenche une erreur de NU1109.
Vous pouvez activer cette fonctionnalité en définissant la propriété MSBuild CentralPackageTransitivePinningEnabled
sur true
dans un projet ou dans un Directory.Packages.props
ou un fichier d’importation Directory.Build.props
:
<PropertyGroup>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>
Épinglage transitif et pack
Lorsqu’un package est épinglé de manière transitive, votre projet utilise une valeur supérieure à celle demandée par vos dépendances. Si vous créez un package à partir de votre projet, afin de vous assurer que votre package fonctionnera correctement, NuGet convertira les dépendances indirectement fixées en dépendances explicites dans le fichier nuspec.
Dans l’exemple suivant, PackageA 1.0.0
a une dépendance sur 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>
Lorsque vous utilisez la commande pack pour créer un package, les deux packages apparaissent dans le groupe de dépendances.
<group targetFramework="net6.0">
<dependency id="PackageA" version="6.12.1" exclude="Build,Analyzers" />
<dependency id="PackageB" version="6.12.1" exclude="Build,Analyzers" />
</group>
Pour cette raison, l'utilisation de l’épinglage transitif doit être soigneusement évaluée lors de l'écriture d'une bibliothèque, car elle peut entraîner des dépendances que vous n’attendiez pas.
Remplacement des versions de paquets
Vous pouvez remplacer une version de package individuelle à l’aide de la propriété VersionOverride
sur un élément <PackageReference />
. Cela remplace toute <PackageVersion />
définie de manière centralisée.
<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>
Vous pouvez désactiver cette fonctionnalité en définissant la propriété MSBuild CentralPackageVersionOverrideEnabled
sur false
dans un projet ou dans un fichier d'import Directory.Packages.props
ou Directory.Build.props
.
<PropertyGroup>
<CentralPackageVersionOverrideEnabled>false</CentralPackageVersionOverrideEnabled>
</PropertyGroup>
Lorsque cette fonctionnalité est désactivée, la spécification d’un VersionOverride
sur n’importe quel élément <PackageReference />
entraîne une erreur au moment de la restauration indiquant que la fonctionnalité est désactivée.
Désactivation de la gestion centralisée des packages
Si vous souhaitez désactiver la gestion centralisée des packages pour un projet particulier, vous pouvez la désactiver en définissant la propriété MSBuild ManagePackageVersionsCentrally
sur false
:
<PropertyGroup>
<ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
</PropertyGroup>
Références de package globales
Note
Cette fonctionnalité est disponible uniquement dans Visual Studio 2022 17.4 ou version ultérieure, .NET SDK 7.0.100.preview7 ou version ultérieure, et NuGet 6.4 ou version ultérieure.
Une référence globale de package est utilisée pour spécifier qu’un package sera utilisé par chaque projet dans un référentiel. Cela inclut les packages qui effectuent le contrôle de version, étendent votre build ou tout autre package requis par tous les projets. Les références globales de package sont ajoutées au groupe d’éléments PackageReference avec les métadonnées suivantes :
IncludeAssets="Runtime;Build;Native;contentFiles;Analyzers"
Cela garantit que le package est utilisé uniquement comme dépendance de développement et empêche toute référence d’assembly au moment de la compilation.PrivateAssets="All"
Cela empêche les références globales de package d’être récupérées par les dépendances en aval.
Les éléments GlobalPackageReference
doivent être placés dans votre Directory.Packages.props
pour être utilisés par tous les projets d'un dépôt.
<Project>
<ItemGroup>
<GlobalPackageReference Include="Nerdbank.GitVersioning" Version="3.5.109" />
</ItemGroup>
</Project>
Avertissement lors de l’utilisation de plusieurs sources de package
Lorsque vous utilisez la gestion centralisée des packages, vous verrez un avertissement NU1507
si vous avez plusieurs sources de package définies dans votre configuration. Pour résoudre cet avertissement, mappez vos sources de package avec mappage de source de package ou spécifiez une source de package unique.
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.
Note
La gestion centralisée des packages est en développement actif. Nous vous remercions de l'essayer et de fournir les commentaires que vous pourriez avoir sur NuGet/Home.