Zentrale Paketverwaltung (CPM)

Die Abhängigkeitsverwaltung ist ein Kernfeature von NuGet. Die Verwaltung von Abhängigkeiten für ein einzelnes Projekt kann einfach sein. Das Verwalten von Abhängigkeiten für Lösungen für mehrerer Projekte kann wiederum schwierig sein, da sie mit der Skalierung in Größe und Komplexität beginnen. In Situationen, in denen Sie gängige Abhängigkeiten für viele verschiedene Projekte verwalten, können Sie die zentralen Paketverwaltungsfeatures (CPM) von NuGet nutzen, um alles ganz einfach von einen einzigen Ort heraus auszuführen.

Bisher wurden NuGet-Paketabhängigkeiten an einem der folgenden beiden Speicherorte verwaltet:

  • packages.config: Eine XML-Datei wird bei älteren Projekttypen für die Verwaltung der Pakete verwendet, auf die vom Projekt verwiesen wird.
  • <PackageReference />: Ein XML-Element wird bei MSBuild Projekten verwendet, um NuGet Paketabhängigkeiten zu definieren.

Ab NuGet 6.2 können Sie Ihre Abhängigkeiten in Ihren Projekten zentral verwalten, indem Sie eine Directory.Packages.props-Datei und eine MSBuild-Eigenschaft hinzufügen.

Das Feature ist für alle in NuGet integrierten Tools ab den folgenden Versionen verfügbar.

Ältere Tools werden die Konfigurationen und Features der zentralen Paketverwaltung ignorieren. Wenn Sie dieses Feature in vollem Umfang verwenden möchten, stellen Sie sicher, dass alle Buildumgebungen die neuesten kompatiblen Toolversionen verwenden.

Die zentrale Paketverwaltung gilt für alle <PackageReference>-basierten MSBuild-Projekte (einschließlich Legacy-CSPROJ), solange die kompatiblen Tools verwendet werden.

Aktivieren der zentralen Paketverwaltung

Um mit der zentralen Paketverwaltung zu beginnen, müssen Sie eine Directory.Packages.props Datei im Stamm ihres Repositorys erstellen und die MSBuild-Eigenschaft ManagePackageVersionsCentrally auf true festlegen.

Darin können Sie unter Verwendung von <PackageVersion />-Elementen, welche die Paket-ID und -version festlegen, die jeweiligen für Ihr Projekt erforderlichen Paketversionen definieren.

<Project>
  <PropertyGroup>
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
  </PropertyGroup>
  <ItemGroup>
    <PackageVersion Include="Newtonsoft.Json" Version="13.0.1" />
  </ItemGroup>
</Project>

Für jedes Projekt definieren Sie anschließend eine <PackageReference /> und überspringen das Version Attribut, da die Version aus einem entsprechenden <PackageVersion /> Element ausgelesen wird.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" />
  </ItemGroup>
</Project>

Jetzt verwenden Sie die zentrale Paketverwaltung und verwalten Ihre Versionen an einem zentralen Speicherort!

Regeln für die zentrale Paketverwaltung

Die Directory.Packages.props-Datei verfügt über eine Reihe von Regeln hinsichtlich der Position, in der sie sich im Verzeichnis eines Repositorys und seinem Kontext befindet. Aufgrund der Einfachheit wird nur eine Directory.Packages.props-Datei für ein bestimmtes Projekt ausgewertet.

Wenn Sie also mehrere Directory.Packages.props-Dateien im Repository hatten, wird die Datei, die dem Verzeichnis Ihres Projekts am nächsten ist, für Sie ausgewertet. Somit erhalten Sie zusätzliche Kontrolle auf verschiedenen Ebenen Ihres Repositorys.

Im folgenden Beispiel sollten Sie die folgende Repositorystruktur berücksichtigen:

Repository
 |-- Directory.Packages.props
 |-- Solution1
     |-- Directory.Packages.props
     |-- Project1
 |-- Solution2
     |-- Project2
  • Project1 wird die Directory.Packages.props Datei im Repository\Solution1\ Verzeichnis auswerten und muss manuell die nächste importieren, falls gewünscht.
    <Project>
      <Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Packages.props, $(MSBuildThisFileDirectory)..))" />
      <ItemGroup>
        <PackageVersion Update="Newtonsoft.Json" Version="12.0.1" />
      </ItemGroup>
    </Project>
    
  • Project2 wertet die Directory.Packages.props-Datei im Repository\-Verzeichnis aus.

Hinweis: MSBuild importiert nicht automatisch jedee Directory.Packages.props für Sie, nur die erste, welche dem Projekt am nächsten ist. Wenn Sie mehrere Directory.Packages.props haben, müssen Sie das übergeordnete Element manuell importieren, während die Stamm Directory.Packages.props das nicht machen würde.

Erste Schritte

Um Ihr Repository vollständig zu integrieren, sollten Sie die folgenden Schritte ausführen:

  1. Erstellen Sie eine neue Datei im Stamm Ihres Repositorys mit dem Namen Directory.Packages.props, in dem Ihre zentral definierten Paketversionen deklariert werden und die MSBuild-Eigenschaft ManagePackageVersionsCentrally auf true festgelegt wird.
  2. Deklarieren Sie <PackageVersion />-Elemente in Ihren Directory.Packages.props.
  3. Deklarieren Sie <PackageReference /> Elemente ohne Version-Attribute in Ihren Projektdateien.

Beziehen Sie sich für eine Idee zum Aussehen Ihrer Quellzuordnungen auf unser Beispielrepository.

Transitives Anheften

Sie können eine transitive Paketversion automatisch außer Kraft setzen, auch ohne explizite oberste Ebene <PackageReference />, indem Sie ein Feature abonnieren, das als „transitives Anheften“ bezeichnet wird. Dadurch wird eine transitive Abhängigkeit von einer Abhängigkeit auf oberster Ebene implizit in Ihrem Auftrag höher gestuft.

Sie können dieses Feature aktivieren, indem Sie die MSBuild-Eigenschaft CentralPackageTransitivePinningEnabled auf true in einem Projekt oder in einer Directory.Packages.props- oder Directory.Build.props-Importdatei festlegen:

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

Außerkraftsetzung von Paketversionen

Sie können eine einzelne Paketversion überschreiben, indem Sie die VersionOverride-Eigenschaft auf einem <PackageReference />-Element verwenden. Dadurch werden alle zentral definierten <PackageVersion /> außer Kraft gesetzt.

<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>

Sie können dieses Feature durch Festlegen der MSBuild-Eigenschaft CentralPackageVersionOverrideEnabled auf false in einem Projekt oder in einer Directory.Packages.props- oder Directory.Build.props-Importdatei deaktivieren:

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

Wenn dieses Feature deaktiviert ist, führt die Angabe eines VersionOverride- oder <PackageReference />-Elements zu einem Fehler beim Wiederherstellungszeitpunkt, der angibt, dass das Feature deaktiviert ist.

Deaktivieren der zentralen Paketverwaltung

Wenn Sie die zentrale Paketverwaltung für ein spezifisches Projekt deaktivieren möchten, können Sie das durch Setzen der MSBuild-Eigenschaft ManagePackageVersionsCentrally auf false tun:

<PropertyGroup>
  <ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
</PropertyGroup>

Globale Paketverweise

Hinweis

Dieses Feature ist nur in Visual Studio 2022 17.4 oder höher, .NET SDK 7.0.100.preview7 oder höher und NuGet 6.4 oder höher verfügbar.

Ein globaler Paketverweis wird verwendet, um anzugeben, dass ein Paket von jedem Projekt in einem Repository verwendet wird. Dazu gehören Pakete, die Versionsverwaltung durchführen, den Build erweitern oder andere Pakete, die von allen Projekten benötigt werden. Globale Paketverweise werden der PackageReference-Elementgruppe mit den folgenden Metadaten hinzugefügt:

  • IncludeAssets="Runtime;Build;Native;contentFiles;Analyzers"
    Dies stellt sicher, dass das Paket nur als Entwicklungsabhängigkeit verwendet wird und verhindert, dass zur Kompilierzeit Assembler-Referenzen vorhanden sind.
  • PrivateAssets="All"
    Dadurch wird verhindert, dass globale Paketverweise von nachgeschalteten Abhängigkeiten aufgenommen werden.

GlobalPackageReference-Elemente sollten in Ihrem Directory.Packages.props-Verzeichnis platziert werden, um von jedem Projekt in einem Repository verwendet zu werden:

<Project>
  <ItemGroup>
    <GlobalPackageReference Include="Nerdbank.GitVersioning" Version="3.5.109" />
  </ItemGroup>
</Project>

Warnung beim Verwenden mehrerer Paketquellen

Wenn Sie die zentrale Paketverwaltung verwenden, wird eine NU1507-Warnung angezeigt, wenn mehrere Paketquellen in Ihrer Konfiguration definiert sind. Um diese Warnung zu beheben, ordnen Sie Ihre Paketquellen mit der Paketquellenzuordnung zu, oder geben Sie eine einzelne Paketquelle an.

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.

Hinweis

Die zentrale Paketverwaltung befindet sich in der aktiven Entwicklung. Wir freuen uns, wenn Sie es ausprobieren und Ihr Feedback unter NuGet/Home bereitstellen.