NuGet-Pakete zentral verwalten
Seit über 12 Jahren ist die Paketverwaltung NuGet Teil des .NET-Ökosystems mit direkten Integrationen in verschiedene IDEs, CLIs und Buildsysteme. Aber ein Feature hat 12 Jahre auf sich warten lassen und braucht sicherlich noch etwas mehr Pflege bis es ausgereift ist!
Die Problematik
Unabhängig von der Strategie für die Versionsverwaltung des Codes, Mono-Repository vs. Poly-Repository, bestand immer die Notwendigkeit, die einzelnen Projekte in den verwendeten Versionen der NuGet-Pakete zu synchronisieren. Gründe dafür sind Kompatibilität und Sicherheit, aber auch neue Funktionalitäten oder Fehlerbehebungen.
Frühere Lösungsansätze
Im Laufe der Jahre haben sich die Anforderungen in diesem Bereich immer weiter entwickelt, so dass die bisherigen Lösungsansätze zunehmend an ihre Grenzen stießen. Nicht nur die einheitliche Verwendung derselben Paketversion, sondern auch die generelle Verwendung eines Pakets in allen zugehörigen Projekten einer Lösung wurde in diesem Zusammenhang aufgenommen und weiterentwickelt. Das Hauptmanko konnte jedoch nie behoben werden, es war bisher immer ein manueller Eingriff durch einen Entwickler notwendig, um die Version der verwendeten Pakete zu aktualisieren. Die bestehenden Integrationen von IDEs und CLIs produzierten mehr Fehler als sie beheben konnten.
Zentral Paketverwaltung (CPM)
Nun wurde dem Wunsch entsprochen und im April 2022 wurde die Zentrale Paketverwaltung (“Central Package Management”, CPM) vorgestellt und zusammen mit NuGet Version 6.2 und einigen ergänzenden Funktionen veröffentlicht.
Um die zentrale Paketverwaltung zu aktivieren, wird die MSBuild-Eigenschaft ManagePackageVersionsCentrally
in der Datei Directory.Packages.props
auf true
gesetzt.
Für die Auflistung und Verwaltung der Versionen werden PackageVersion
Elemente benötigt, die jeweils den Paketnamen und die zu verwendende Version enthalten. Als nächster Schritt muss das Attribut Version
aus allen PackageReference
Elementen in den Projektdateien entfernt werden. Damit ist die Lösung migriert und verwendet von nun an die zentrale Paketverwaltung.
Zusatzfeature: Transitives Anhängen
Mit der MSBuild-Eigenschaft CentralPackageTransitivePinningEnabled
auf true
wird NuGet angewiesen, alle transitiven Abhängigkeiten von ihren explizit definierten Abhängigkeiten zu aktualisieren. Diese Eigenschaft kann sowohl in der Directory.Build.props
als auch in der bereits erwähnten Directory.Packages.props
gesetzt werden.
Zusätzliches Feature: Globale Paketreferenz
Ein weiteres Feature ist die GlobalPackageReference
, mit der ein Paket in jedem Projekt der Solution / des Repositories referenziert werden kann, wie z.B. Code-Analyzer. Diese Art der Paketreferenzierung sollte auch in Directory.Packages.props
erfolgen.
Zusammenfassung
Alles in allem eine großartige Weiterentwicklung des NuGet Systems. Allerdings gibt es derzeit noch einige Probleme mit der Integration von Visual Studio oder .NET CLI.
Beide Integrationen sind in der Lage die Paketreferenzen auszuwerten und die Pakete wiederherzustellen. Allerdings wird bei einem Update mit Visual Studio die XML-Struktur des Projektes fehlerhaft aktualisiert, so dass manuelle Nacharbeiten erforderlich sind.
Wenn die .NET CLI eine Referenz zu einem Projekt hinzufügen möchte, wird CPM ignoriert und es kommt erneut zu Buildfehlern.
Das sollte aber nicht abschrecken, denn bestehende Integrationen wie z.B. GitHubs Dependabot liefern hervorragende Ergebnisse.