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 simple. La gestion des dépendances pour les solutions multi-projets peut s’avérer difficile à mesure qu’elles commencent à grandir et à se complexifier. 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 la gestion centralisée des packages (CPM) NuGet pour effectuer toutes ces opération dans un emplacement unique.

Historiquement, les dépendances de package NuGet ont été gérées à l’un des deux emplacements suivants :

  • packages.config – Un fichier XML utilisé dans des types de projets plus anciens pour gérer la liste des packages référencés par le projet.
  • <PackageReference /> - Un élément XML utilisé dans les projets MSBuild qui définit les dépendances de package NuGet.

À partir de NuGet 6.2, vous pouvez gérer de manière centralisée les dépendances dans les projets avec l’ajout d’un fichier Directory.Packages.props et d’une propriété MSBuild.

Cette fonctionnalité est disponible dans tous les outils intégrés NuGet, à partir des versions suivantes.

Les outils plus anciens ignorent les configurations et fonctionnalités de gestion centralisée des packages. Pour utiliser cette fonctionnalité dans son intégralité, assurez-vous que tous vos environnements de génération 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 CSPROJ hérités) du moment que des outils compatibles sont utilisés.

Activer la gestion centralisée des packages

Pour commencer à utiliser la gestion centralisée des packages, 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.

À l’intérieur, vous définissez ensuite chacune des versions de package respectives requises de vos projets à l’aide d’éléments <PackageVersion /> qui définissent l’ID de package 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 un attribut <PackageReference /> mais omettez l’attribut Version, car la version sera atteinte à partir d’un élément <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 gérez vos versions dans un emplacement central !

Règles de gestion centralisée des packages

Le fichier Directory.Packages.props a un certain nombre de 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
  • Projet1 évalue le fichier Directory.Packages.props dans le répertoire Repository\Solution1\ et il doit importer manuellement le suivant si désiré.
    <Project>
      <Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Packages.props, $(MSBuildThisFileDirectory)..))" />
      <ItemGroup>
        <PackageVersion Update="Newtonsoft.Json" Version="12.0.1" />
      </ItemGroup>
    </Project>
    
  • Projet2 évalue le fichier Directory.Packages.props dans le répertoire Repository\.

Remarque : MSBuild n’importe pas automatiquement chaque Directory.Packages.props pour vous, il n’importe que le plus proche du projet. Si vous avez plusieurs Directory.Packages.props, vous devez importer le parent manuellement alors que le Directory.Packages.props de la racine ne le ferait pas.

Bien démarrer

Pour intégrer entièrement votre référentiel, procédez comme suit :

  1. Créez un nouveau 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é MSBuild ManagePackageVersionsCentrally sur true.
  2. Déclarez les éléments <PackageVersion /> dans votre Directory.Packages.props.
  3. Déclarez les éléments <PackageReference /> sans attributs Version dans vos fichiers projet.

Pour avoir une idée de la façon de ce à quoi la gestion centralisée des packages peut ressembler, reportez-vous à notre référentiel d’exemples.

Épinglage transitif

Vous pouvez remplacer automatiquement une version de package transitive, même sans niveau supérieur <PackageReference /> explicite, en optant pour une fonctionnalité appelée épinglage transitive. Cela favorise une dépendance transitive vers une dépendance de niveau supérieur implicitement en votre nom si nécessaire.

Vous pouvez activer cette fonctionnalité en définissant la propriété MSBuild CentralPackageTransitivePinningEnabled sur true dans un projet ou dans un fichier d’importation Directory.Packages.props ou Directory.Build.props :

<PropertyGroup>
  <CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>

Remplacement des versions de package

Vous pouvez remplacer une version de package individuelle à l’aide de la propriété VersionOverride sur un élément <PackageReference />. Cela remplace tous les <PackageVersion /> définies 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’importation Directory.Packages.props ou Directory.Build.props :

<PropertyGroup>
  <CentralPackageVersionOverrideEnabled>false</CentralPackageVersionOverrideEnabled>
</PropertyGroup>

Quand cette fonctionnalité est désactivée, la spécification de VersionOverride sur un élément <PackageReference /> quel qu’il soit entraîne une erreur au moment de la restauration indiquant que la fonctionnalité est désactivée.

Désactiver 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 global

Remarque

Cette fonctionnalité est uniquement disponible 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 de package global 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 génération ou tout autre package requis par tous les projets. Les références de package global 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 de package global 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 chaque projet d’un référentiel :

<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 plusieurs sources de package sont définies dans votre configuration. Pour résoudre cet avertissement, mappez vos sources de package avec le 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.

Remarque

La gestion centralisée des packages est activement développé. Nous vous remercions de l’essayer et vous invitons à nous faire part de tous les commentaire que vous que vous pourriez avoir dans NuGet/Home.