Freigeben über


PackageReference in Projektdateien

Paketbezüge, die <PackageReference>-MSBuild Elemente verwenden, geben NuGet Paketabhängigkeiten direkt in Projektdateien an, anstatt eine separate packages.config-Datei zu haben. Die Verwendung von PackageReference hat keine Auswirkungen auf andere Aspekte von NuGet. Einstellungen in Dateien vom Typ NuGet.Config (Paketquellen eingeschlossen) gelten beispielsweise weiterhin wie unter Gängige NuGet-Konfigurationen beschrieben.

Mit PackageReference können Sie auch MSBuild-Bedingungen für die Auswahl von Paketverweisen pro Zielframework oder anderen Gruppierungen verwenden. Zudem lässt er eine präzise Steuerung der Abhängigkeiten und des Inhaltsflusses zu. (Weitere Informationen finden Sie unter NuGet Pack und Wiederherstellen als MSBuild-Ziele.)

Unterstützung für Projekttypen

Standardmäßig wird PackageReference für .NET-Projekte, .NET Standard-Projekte und UWP-Projekte für Windows 10 Build 15063 (Creators Update) und höher verwendet, mit Ausnahme von C++-UWP-Projekten. .NET Framework-Projekte unterstützen PackageReference. Standardmäßig wird jedoch packages.config verwendet. Um PackageReference in einem .NET Framework-Projekt zu verwenden, migrieren Sie die Abhängigkeiten aus packages.config ihrer Projektdatei, und entfernen Sie dann packages.config.

ASP.NET Apps, die auf das vollständige .NET Framework abzielen, enthalten nur eingeschränkte Unterstützung für PackageReference. C++- und JavaScript-Projekttypen werden nicht unterstützt.

Hinzufügen einer PackageReference

Fügen Sie mit der folgenden Syntax eine Abhängigkeit in Ihrer Projektdatei hinzu:

<ItemGroup>
    <!-- ... -->
    <PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0" />
    <!-- ... -->
</ItemGroup>

Steuern die Abhängigkeitsversion

Die Konvention für die Angabe der Version eines Pakets entspricht der Verwendung von packages.config:

<ItemGroup>
    <!-- ... -->
    <PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0" />
    <!-- ... -->
</ItemGroup>

Im obigen Beispiel bedeutet 3.6.0 jede Version, die =3.6.0 mit der Einstellung für die niedrigste Version ist >, wie in der Paketversionsverwaltung beschrieben.

Verwenden von PackageReference für ein Projekt ohne Paketabhängigkeiten

Erweitert: Wenn Sie keine Pakete in einem Projekt installiert haben (keine PackageReferences in der Projektdatei oder der packages.config-Datei), aber das Projekt mit dem Format von PackageReference wiederherstellen möchten, können Sie in der Projektdatei eine RestoreProjectStyle-Projekteigenschaft auf PackageReference festlegen.

<PropertyGroup>
    <!--- ... -->
    <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
    <!--- ... -->
</PropertyGroup>    

Dies kann hilfreich sein, wenn Sie auf Projekte verweisen, die "PackageReference" formatiert sind (vorhandene Csproj- oder SDK-Formatvorlagenprojekte). Dadurch kann Ihr Projekt „transitiv“ auf die Pakete verweisen, auf die diese Projekte verweisen.

PackageReference und Quellen

In PackageReference-Projekten werden transitive Abhängigkeitsversionen zur Wiederherstellungszeit aufgelöst. In PackageReference-Projekten müssen alle Quellen für alle Wiederherstellungen verfügbar sein.

Unverankerte Versionen

Unverankerte Versionen werden mit PackageReference unterstützt:

<ItemGroup>
    <!-- ... -->
    <PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.*" />
    <PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0-beta.*" />
    <!-- ... -->
</ItemGroup>

Steuern von Abhängigkeitsobjekten

Sie verwenden eine Abhängigkeit möglicherweise rein als Entwicklungsumgebung und möchten diese nicht für Projekte verfügbar machen, die Ihr Paket nutzen. In diesem Szenario können Sie dieses Verhalten über die PrivateAssets-Metadaten steuern.

<ItemGroup>
    <!-- ... -->

    <PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0">
        <PrivateAssets>all</PrivateAssets>
    </PackageReference>

    <!-- ... -->
</ItemGroup>

Mit den folgenden Metadatentags werden Abhängigkeitsobjekte gesteuert:

Tag Description Standardwert
IncludeAssets Diese Objekte werden verbraucht all
ExcludeAssets Diese Objekte werden nicht verbraucht none
PrivateAssets Diese Objekte werden verbraucht, aber nicht in das übergeordnete Projekt übertragen contentfiles;analyzers;build

Zulässige Werte für diese Tags sind wie folgt, wobei mehrere Werte durch ein Semikolon getrennt sind, mit Ausnahme von all und none, die von sich selbst angezeigt werden müssen:

Value Description
compile Inhalt des Ordners lib und steuert, ob Ihr Projekt anhand der Assemblys im Ordner kompiliert werden kann
runtime Inhalt der Ordner lib und runtimes und steuert, ob diese Assemblys in das Buildausgabeverzeichnis kopiert werden
contentFiles Inhalte des Ordners contentfiles
build .props und .targets im Ordner build
buildMultitargeting (4.0).props und .targets im Ordner buildMultitargeting für frameworkübergreifende Zielplattformen
buildTransitive (5.0 und höher).props und .targets im Ordner buildTransitive für Ressourcen, die transitiv in beliebige verarbeitende Projekte eingefügt werden. Weitere Informationen finden Sie auf der Seite Feature.
analyzers .NET-Analysegeräte
native Inhalte des Ordners contentfiles
none Keiner der obigen Werte wird verwendet.
all Alle oben genannten Werte (mit Ausnahme von 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>

Beachten Sie Folgendes: Da build nicht in PrivateAssets enthalten ist, werden Ziele und Eigenschaften an das übergeordnete Projekt übergeben. Angenommen, der obenstehende Verweis wird in einem Projekt verwendet, in dem ein NuGet-Paket mit dem Namen AppLogger erstellt wird. AppLogger kann die Ziele und Eigenschaften aus Contoso.Utility.UsefulStuff verarbeiten, wie Projekte, die AppLogger verarbeiten.

Note

Wenn developmentDependency in einer .nuspec-Datei auf true festgelegt ist, kennzeichnet dies ein Paket mit einer Abhängigkeit, die nur für die Entwicklung gilt. Dadurch wird vermieden, dass das Paket als Abhängigkeit in andere Pakete eingefügt wird. Bei PackageReference (NuGet 4.8+) bedeutet dieses Flag auch, dass Objekte zur Kompilierzeit von der Kompilierung ausgeschlossen werden. Weitere Informationen finden Sie unter DevelopmentDependency support for PackageReference (DevelopmentDependency-Unterstützung für PackageReference).

Hinzufügen einer PackageReference-Bedingung

Sie können eine Bedingung verwenden, um zu steuern, ob ein Paket enthalten ist. Bedingungen können eine beliebige MSBuild-Variable oder eine Variable verwenden, die in der Ziel- oder Propsdatei definiert ist. Derzeit wird jedoch nur die TargetFramework Variable unterstützt.

Nehmen Wir beispielsweise an, Sie richten netstandard1.4 sich genauso net452 wie eine Abhängigkeit aus, die nur für net452. In diesem Fall möchten Sie nicht, dass ein netstandard1.4 Projekt, das Ihr Paket nutzt, diese unnötige Abhängigkeit hinzufügen soll. Sie geben in der PackageReference eine Bedingung an, um dies zu verhindern, die wie folgt lautet:

<ItemGroup>
    <!-- ... -->
    <PackageReference Include="Newtonsoft.Json" Version="9.0.1" Condition="'$(TargetFramework)' == 'net452'" />
    <!-- ... -->
</ItemGroup>

Ein Paket, das in diesem Projekt erstellt wurde, zeigt an, dass die Datei „Newtonsoft.json“ nur als Abhängigkeit für ein net452-Ziel enthalten ist:

The result of applying a Condition on PackageReference with VS2017Das Ergebnis der Anwendung einer Bedingung auf die PackageReference mit VS2017

Bedingungen können auch auf der ItemGroup-Ebene angewendet werden und gelten dann für alle untergeordneten PackageReference-Elemente:

<ItemGroup Condition = "'$(TargetFramework)' == 'net452'">
    <!-- ... -->
    <PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
    <PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0" />
    <!-- ... -->
</ItemGroup>

GeneratePathProperty

Dieses Feature ist mit NuGet 5.0 oder höher und mit Visual Studio 2019 16.0 oder höher verfügbar.

Manchmal ist es wünschenswert, von einem MSBuild-Ziel aus auf Dateien in einem Paket zu verweisen. In packages.config-basierten Projekten werden die Pakete in einem Ordner mit Bezug zur Projektdatei installiert. Bei PackageReference werden die Pakete hingegen aus dem Ordner global-packagesverwendet, der von Computer zu Computer variieren kann.

Um diese Lücke zu schließen, wurde in NuGet eine Eigenschaft eingeführt, die auf den Speicherort verweist, von dem aus das Paket verwendet wird.

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>

Darüber hinaus generiert NuGet automatisch Eigenschaften für Pakete, die einen Toolsordner enthalten.

  <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-Eigenschaften und Paketidentitäten haben nicht die gleichen Einschränkungen, sodass die Paketidentität in einen MSBuild-Anzeigenamen geändert werden muss, dem das Wort Pkg vorangestellt ist. Beachten Sie die generierte nuget.g.props-Datei, um den genauen Namen der generierten Eigenschaft zu überprüfen.

PackageReference-Aliase

In einigen seltenen Fällen enthalten unterschiedliche Pakete Klassen im selben Namespace. Ab NuGet 5.7 und Visual Studio 2019 Update 7 unterstützt PackageReference ebenso wie ProjectReference Aliases. Standardmäßig werden keine Aliase bereitgestellt. Wenn ein Alias angegeben wird, müssen alle Assemblys, die aus dem kommentierten Paket stammen, mit einem Alias referenziert werden.

Sie können sich die Beispielverwendung unter NuGet\Samples ansehen.

In der Projektdatei können Sie die Aliasse folgendermaßen angeben:

  <ItemGroup>
    <PackageReference Include="NuGet.Versioning" Version="5.8.0" Aliases="ExampleAlias" />
  </ItemGroup>

Verwenden Sie ihn im Code wie folgt:

extern alias ExampleAlias;

namespace PackageReferenceAliasesExample
{
...
        {
            var version = ExampleAlias.NuGet.Versioning.NuGetVersion.Parse("5.0.0");
            Console.WriteLine($"Version : {version}");
        }
...
}

NuGet-Warnungen und -Fehler

Dieses Feature ist mit NuGet 4.3 oder höher und mit Visual Studio 2017 15.3 oder höher verfügbar.

Für viele Pack- und Wiederherstellungsszenarios werden alle NuGet-Warnungen und -Fehler codiert, und sie beginnen mit NU****. Alle NuGet-Warnungen und -Fehler sind in der Referenz-Dokumentation aufgeführt.

NuGet beachtet die folgenden Warnungseigenschaften:

  • TreatWarningsAsErrors, behandeln Sie alle Warnungen als Fehler.
  • WarningsAsErrors, behandeln Sie bestimmte Warnungen als Fehler.
  • NoWarn, bestimmte Warnungen ausblenden, entweder projekt- oder paketweit.

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>

Unterdrücken von NuGet-Warnungen

Es wird empfohlen, alle NuGet-Warnungen während der Pack- und Wiederherstellungsvorgänge aufzulösen; in bestimmten Situationen wird deren Auflösung verlangt. Für die projektweite Unterdrückung einer Warnung sollten Sie Folgendes in Erwägung ziehen:

<PropertyGroup>
    <PackageVersion>5.0.0</PackageVersion>
    <NoWarn>$(NoWarn);NU5104</NoWarn>
</PropertyGroup>
<ItemGroup>
    <PackageReference Include="Contoso.Package" Version="1.0.0-beta.1"/>
</ItemGroup>

Gelegentlich beziehen sich Warnungen nur auf ein bestimmtes Paket im Graph. Sie können diese Warnung selektiv unterdrücken, indem Sie ein NoWarn Element zum PackageReference-Element hinzufügen.

<PropertyGroup>
    <PackageVersion>5.0.0</PackageVersion>
</PropertyGroup>
<ItemGroup>
    <PackageReference Include="Contoso.Package" Version="1.0.0-beta.1" NoWarn="NU1603" />
</ItemGroup>

Unterdrücken von Warnungen für NuGet-Pakete in Visual Studio

In Visual Studio ist das Unterdrücken von Warnungen auch über die IDE möglich.

Sperren von Abhängigkeiten

Dieses Feature ist mit NuGet 4.9 oder höher und mit Visual Studio 2017 15.9 oder höher verfügbar.

Die Eingabe für die NuGet-Wiederherstellung ist ein Satz von PackageReference-Elementen aus der Projektdatei (oberste Ebene oder direkte Abhängigkeiten). Die Ausgabe ist der vollständige Abschluss aller Paketabhängigkeiten einschließlich transitiver Abhängigkeiten. NuGet versucht immer, den gleichen vollständigen Abschluss von Paketabhängigkeiten zu erzeugen, wenn sich die PackageReference-Eingabeliste nicht geändert hat. Es gibt jedoch einige Szenarien, in denen dies nicht möglich ist. Beispiel:

  • Beim Verwenden von unverankerten Versionen wie <PackageReference Include="My.Sample.Lib" Version="4.*"/>. Während die Absicht hierbei darin liegt, bei jeder Wiederherstellung die neueste Version zu verwenden, gibt es Szenarien, in denen Benutzer anfordern, dass der Paketgraph auf eine bestimmte neueste Version festgelegt und zu einem späteren Zeitpunkt ggf. explizit eine höhere Version geändert werden kann.

  • Eine neuere Version des Pakets, die den Anforderungen an die PackageReference-Version entspricht, wird veröffentlicht. Beispiel:

    • Tag 1: Wenn Sie angegeben <PackageReference Include="My.Sample.Lib" Version="4.0.0"/> haben, aber die in den NuGet-Repositorys verfügbaren Versionen waren 4.1.0, 4.2.0 und 4.3.0. In diesem Fall wäre NuGet auf 4.1.0 (nächste Mindestversion) aufgelöst worden.

    • Tag 2: Version 4.0.0 wird veröffentlicht. NuGet findet nun die genaue Übereinstimmung und beginnt mit der Auflösung von 4.0.0.

  • Eine bestimmte Paketversion wird aus dem Repository entfernt. Auch wenn nuget.org das Löschen von Paketen nicht erlaubt, weisen nicht alle Paketrepositorys diese Einschränkung auf. Daher sucht NuGet nach der besten Übereinstimmung, wenn die gelöschte Version nicht verwendet werden kann.

Aktivieren der Sperrdatei

Um das vollständige Schließen von Paketabhängigkeiten beizubehalten, können Sie sich für das Sperrdateifeature anmelden, indem Sie die MSBuild-Eigenschaft RestorePackagesWithLockFile für Ihr Projekt festlegen:

<PropertyGroup>
    <!--- ... -->
    <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
    <!--- ... -->
</PropertyGroup>    

Wenn diese Eigenschaft festgelegt ist, generiert NuGet-Wiederherstellung eine Sperrdatei (packages.lock.json) im Projektstammverzeichnis, die alle Paketabhängigkeiten auflistet.

Note

Sobald ein Projekt eine packages.lock.json-Datei im Stammverzeichnis enthält, wird die Sperrdatei bei der Wiederherstellung immer verwendet, auch wenn die Eigenschaft RestorePackagesWithLockFile nicht festgelegt ist. Eine andere Möglichkeit zur Verwendung dieser Funktion besteht also darin, eine leere packages.lock.json-Dummydatei im Stammverzeichnis des Projekts zu erstellen.

restore-Verhalten mit Sperrdatei

Wenn eine Sperrdatei für ein Projekt vorhanden ist, verwendet NuGet diese Sperrdatei zum Ausführen restore. NuGet überprüft schnell, ob änderungen an den Paketabhängigkeiten vorgenommen wurden, wie in der Projektdatei erwähnt (oder abhängige Projektdateien), und wenn keine Änderungen vorgenommen wurden, werden nur die in der Sperrdatei erwähnten Pakete wiederhergestellt. Es erfolgt keine erneute Auswertung der Paketabhängigkeiten.

Wenn NuGet eine Änderung bei den in den Projektdateien definierten Abhängigkeiten ermittelt, wird der Paketgraph erneut ausgewertet, und die Sperrdatei wird aktualisiert, um den neuen Paketabschluss für das Projekt widerzuspiegeln.

Für CI/CD- und andere Szenarien, in denen Paketabhängigkeiten nicht dynamisch geändert werden dürfen, können Sie dies erreichen, indem Sie lockedmode auf true festlegen:

Führen Sie für dotnet.exe folgenden Befehl aus:

> dotnet.exe restore --locked-mode

Führen Sie für msbuild.exe folgenden Befehl aus:

> msbuild.exe -t:restore -p:RestoreLockedMode=true

Sie können diese bedingte MSBuild-Eigenschaft auch in Ihrer Projektdatei festlegen:

<PropertyGroup>
    <!--- ... -->
    <RestoreLockedMode>true</RestoreLockedMode>
    <!--- ... -->
</PropertyGroup> 

Wenn der Sperrmodus true lautet, gilt Folgendes: Bei der Wiederherstellung werden entweder die Pakete genau so wiederhergestellt wie in der Sperrdatei aufgelistet, oder es tritt ein Fehler auf, wenn Sie die definierten Paketabhängigkeiten für das Projekt nach dem Erstellen der Sperrdatei aktualisiert haben.

Einbinden der Sperrdatei als Teil Ihres Quellrepositorys

Wenn Sie eine Anwendung erstellen, eine ausführbare Datei und das betreffende Projekt am Anfang der Abhängigkeitskette liegt, überprüfen Sie die Sperrdatei im Quellcode-Repository, damit NuGet sie während der Wiederherstellung nutzen kann.

Wenn Ihr Projekt jedoch ein Bibliotheksprojekt ist, das Sie nicht versenden oder ein gemeinsames Codeprojekt, von dem andere Projekte abhängen, sollten Sie die Sperrdatei nicht als Teil des Quellcodes einchecken. Es gibt keinen Schaden daran, die Sperrdatei beizubehalten, aber die gesperrten Paketabhängigkeiten für das allgemeine Codeprojekt können nicht verwendet werden, wie in der Sperrdatei aufgeführt, während der Wiederherstellung/Erstellung eines Projekts, das von diesem allgemeinen Codeprojekt abhängt.

Example:

ProjectA
  |------> PackageX 2.0.0
  |------> ProjectB
             |------>PackageX 1.0.0

Wenn ProjectA eine Abhängigkeit von einer PackageX-Version 2.0.0 aufweist und auch auf ProjectB verweist, das von der PackageX-Version 1.0.0 abhängig ist, listet die Sperrdatei für ProjectB eine Abhängigkeit von der PackageX-Version 1.0.0 auf. Wenn ProjectA jedoch erstellt wird, enthält die Sperrdatei eine Abhängigkeit von der PackageX-Version 2.0.0 und nicht von 1.0.0, wie in der Sperrdatei für ProjectB aufgelistet. Daher hat die Sperrdatei eines Projekts mit gemeinsamem Code nur wenig Aussagekraft für die verwendeten Pakete für Projekte, die von diesem Projekt abhängig sind.

Erweiterbarkeit der Sperrdatei

Sie können mit einer Sperrdatei verschiedene Verhaltensweisen der Wiederherstellung steuern, wie im Folgenden beschrieben:

Option NuGet.exe dotnet-Option Entsprechende MSBuild-Option Description
-UseLockFile --use-lock-file RestorePackagesWithLockFile Ermöglicht die Verwendung einer Sperrdatei.
-LockedMode --locked-mode RestoreLockedMode Ermöglicht den Sperrmodus für die Wiederherstellung. Dies ist nützlich in CI/CD-Szenarien, in denen Sie wiederholbare Builds wünschen.
-ForceEvaluate --force-evaluate RestoreForceEvaluate Diese Option ist nützlich bei Paketen, bei denen im Projekt unverankerte Versionen definiert sind. Standardmäßig aktualisiert die NuGet-Wiederherstellung die Paketversion nicht automatisch bei jedem Wiederherstellungsvorgang, wenn Sie diesen Vorgang nicht mit dieser Option ausführen.
-LockFilePath --lock-file-path NuGetLockFilePath Definiert einen benutzerdefinierten Speicherort der Sperrdatei für ein Projekt. Standardmäßig unterstützt NuGet packages.lock.json im Stammverzeichnis. Wenn Sie über mehrere Projekte im gleichen Verzeichnis verfügen, unterstützt NuGet die projektspezifische Sperrdatei packages.<project_name>.lock.json.

NuGet-Abhängigkeitslöser

Der NuGet-Abhängigkeitslöser folgt den vier Regeln, wie im Dokument zur Abhängigkeitsauflösung beschrieben.

Um die Leistung und Skalierbarkeit des Wiederherstellungsvorgangs zu verbessern, wurde der Wiederherstellungsalgorithmus in der Version 6.12 umgeschrieben. Ab der Version 6.12 ist der neue Wiederherstellungsalgorithmus für alle PackageReference-Projekte standardmäßig aktiviert. Der neue Wiederherstellungsalgorithmus ist zwar funktionell gleichwertig mit dem vorherigen, aber wie bei jeder Software sind Fehler möglich. Wenn Sie zur vorherigen Implementierung zurückkehren möchten, stellen Sie die MSBuild-Eigenschaft RestoreUseLegacyDependencyResolver auf true.

Sollten Sie Wiederherstellungsfehler in 6.12, .NET 9 oder 17.12 feststellen, die in früheren Versionen nicht reproduzierbar waren, melden Sie bitte einen Fehler auf GitHub. Etwaige Unterschiede zwischen dem alten und dem neuen Algorithmus können sich unterschiedlich auswirken, z. B. bei der Kompilierung oder zur Laufzeit. Es besteht auch die Möglichkeit, dass Änderungen nicht zu Fehlern führen, sondern dass unterschiedliche Paketversionen wiederhergestellt werden. Wenn Sie der Meinung sind, dass Sie von Änderungen betroffen sind, gehen Sie folgendermaßen vor, um zu überprüfen, ob die Änderungen im NuGet-Wiederherstellungsalgorithmus die Ursache sind.

Stellen Sie die Ergebnisse im MSBuildProjectExtensionsPath-Verzeichnis wieder her, die mit den neuen und alten Algorithmen verglichen werden können, um Unterschiede zu finden. In der Regel ist dies der obj-Ordner Ihres Builds. Für die nächsten Schritte können Sie msbuild.exe oder dotnet.exe verwenden.

  1. Entfernen Sie den obj-Ordner für Ihr Projekt.

  2. Ausführen von msbuild -t:restore

  3. Speichern Sie den Inhalt von obj an einem Ort, der angibt, dass es sich um das Verhalten von new handelt.

  4. Führen Sie msbuild -t:restore -p:RestoreUseLegacyDependencyResolver="true" aus.

  5. Speichern Sie den Inhalt von obj an einem Ort, der angibt, dass es sich um das Verhalten von new handelt.

  6. Vergleichen Sie die Dateien in den beiden Verzeichnissen, insbesondere project.assets.json.

    Tools, die Unterschiede hervorheben können, sind hierfür besonders nützlich (z. B. in Visual Studio Code öffnen Sie beide Dateien, und klicken Sie mit der rechten Maustaste auf "Zum Vergleichen auswählen" und "Vergleichen mit ausgewählt").

Wenn Sie der obigen Methode folgen, sollte genau 1 Unterschied zwischen den project.assets.json Dateien bestehen:

      "projectStyle": "PackageReference",
+     "restoreUseLegacyDependencyResolver": true,
      "fallbackFolders": [

Wenn es weitere Unterschiede gibt, melden Sie bitte einen Fehler auf GitHub mit allen Details.

AssetTargetFallback

Mit der Eigenschaft AssetTargetFallback können Sie zusätzliche kompatible Frameworkversionen für Projekte angeben, auf die Ihr Projekt verweist, sowie Frameworkversionen für NuGet-Pakete angeben, die Ihr Projekt nutzt.

Wenn Sie mit PackageReference eine Paketabhängigkeit angeben, aber das entsprechende Paket keine Objekte enthält, die mit dem Zielframework Ihres Projekts kompatibel sind, kommt die Eigenschaft AssetTargetFallback ins Spiel. Die Kompatibilität des referenzierten Pakets wird erneut anhand jedes Zielframeworks überprüft, das in AssetTargetFallback angegeben ist. Wenn über AssetTargetFallback auf project oder package verwiesen wird, wird die Warnung NU1701 ausgelöst.

In der Tabelle unten finden Sie Beispiele, wie sich AssetTargetFallback auf die Kompatibilität auswirkt.

Projektframework AssetTargetFallback Paketframeworks Result
.NET Framework 4.7.2 .NET-Standard 2.0 .NET-Standard 2.0
.NET Core 3.1-App .NET Standard 2.0, .NET Framework 4.7.2 .NET-Standard 2.0
.NET Core 3.1-App .NET Framework 4.7.2 Inkompatibel: Bei NU1202 tritt ein Fehler auf.
.NET Core 3.1-App net472;net471 .NET Framework 4.7.2 .NET Framework 4.7.2 mit NU1701

Mithilfe von ; als Trennzeichen können mehrere Frameworks angegeben werden. Wenn Sie ein Fallbackframework hinzufügen möchten, haben Sie die folgende Möglichkeit:

<AssetTargetFallback Condition=" '$(TargetFramework)'=='netcoreapp3.1' ">
    $(AssetTargetFallback);net472;net471
</AssetTargetFallback>

Sie können $(AssetTargetFallback) auslassen, wenn Sie eine Überschreibung durchführen möchten, anstatt eine Hinzufügung zu den vorhandenen AssetTargetFallback-Werten vorzunehmen.

Note

Wenn Sie ein auf dem .NET SDK basierendes Projekt verwenden, werden entsprechende $(AssetTargetFallback)-Werte konfiguriert. Sie müssen diese nicht manuell festlegen.

Bei $(PackageTargetFallback) handelt es sich um ein früheres Feature, das diese Herausforderung lösen sollte. Dieses Feature funktioniert jedoch nicht und sollte nicht verwendet werden. Wenn Sie von $(PackageTargetFallback) zu $(AssetTargetFallback) migrieren möchten, ändern Sie einfach den Eigenschaftenname.

PrunePackageReference

Die .NET-Runtime entwickelt sich ständig weiter, mit Leistungsverbesserungen und neuen APIs jeder Version. Neue Features, die .NET hinzugefügt werden, werden manchmal auch als Pakete bereitgestellt, sodass Entwickler, die ältere Zielframeworks verwenden, die Bibliothek verwenden können, z. B. System.Text.Json. Dies kann häufig zu einer System.Text.Json 8.0.0 in einem Projekt führen, das auf .NET 9 oder .NET 8ausgerichtet ist. Diese Abhängigkeit ist unnötig, und die Konfliktauflösung des Builds würde die Assembly aus dem Paket nicht verwenden, da sie bereits in der .NET-Runtime verfügbar ist. Ab NuGet Version 6.13 und .NET SDK 9.0.200 PrunePackageReference wird das Bereinigen dieser Pakete bei der Wiederherstellung für .NET SDK-basierte Projekte ermöglicht. Die erste Iteration des Beschneidens betraf nur transitive Pakete, aber ab .NET SDK 10 wirkt sich das Beschneiden auch auf direkte Pakete aus.

Die Paketbereinigung ist als Opt-In-Funktion mit dem .NET 9 SDK verfügbar und ist standardmäßig für alle Frameworks eines Projekts aktiviert, das im .NET 10 SDK ausgerichtet >= .NET 10.0 ist.

Die Paketbeschneidung ist nur mit dem standardmäßigen Abhängigkeitsauflöser verfügbar, da in 6.12veröffentlicht wurde.

PrunePackageReference-Spezifikation

Die Liste der zu löschenden Pakete wird mit dem PrunePackageReference Element definiert.

Attributes Description
Version Gibt die maximale Version an, die gekürzt werden soll. 1.0.0 bedeutet, dass alle Pakete bis einschließlich 1.0.0 gekürzt werden. Für 1.0.0werden 0.9.0 und 1.0.0 gekürzt, aber 1.0.1 wird nicht.

Die folgenden Eigenschaften können verwendet werden, um das Beschneidungsverhalten zu ändern.

PropertyName Description
RestoreEnablePackagePruning Ermöglicht das Beschneiden der Pakete, die mit PrunePackageReferenceangegeben sind. Diese Eigenschaft gilt für jedes Zielframework, und die gültigen Werte sind true und false. Die Standardwerte können sich je nach .NET SDK unterscheiden, wie oben definiert.

Das .NET SDK definiert die Liste der Pakete, die für Sie gelöscht werden sollen.

Funktionsweise von PrunePackageReference

Wenn ein Paket angegeben wird, das während der Wiederherstellung gelöscht werden soll, wird es aus dem Abhängigkeitsdiagramm entfernt. Wenn ein Paket gelöscht wird, gibt es eine Meldung, die bei detaillierter Ausführlichkeit sichtbar ist und angibt, dass das Paket für das angegebene Zielframework entfernt wurde.

Bei transitiven Paketen, d. h. Abhängigkeiten anderer Pakete oder Projekte, werden die Pakete nicht heruntergeladen und werden in keiner der Ausgaben von NuGet angezeigt.

Für direkte Pakete werden PrivateAssets='all' und IncludeAssets='none' implizit angewendet.

  • IncludeAssets='none' Stellt sicher, dass die Assemblys aus diesem Paket während des Builds nicht verwendet werden. Bevor das Beschneiden existierte, stellte die Konfliktlösung während des Builds sicher, dass Plattformassemblies gegenüber denen aus den Paketen bevorzugt wurden.
  • PrivateAssets='all' stellt sicher, dass die Pakete nicht in anderen Paketen oder über Projektverweise berücksichtigt werden.

Example:

Ein Projekt wie unten:

  <PropertyGroup>
    <TargetFrameworks>net9.0;netstandard2.0</TargetFrameworks>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="System.Text.Json" Version="9.0.4" />
  </ItemGroup>

hat eine Nuspec mit den folgenden Abhängigkeiten:

<dependencies>
    <group targetFramework=".NETFramework4.7.2">
        <dependency id="System.Text.Json" version="9.0.4" />
    </group>
    <group targetFramework="net9.0">
    </group>
</dependencies>

Wenn eine direkte Paketreferenz vollständig aus Ihrem Projekt entfernt werden kann und eines der Projekt-Frameworks .NET 10 oder höher ist, wird NU1510 ausgelöst, um Sie aufzufordern, das Paket zu entfernen. Nach diesem Vorschlag wird die Komplexität Ihres Projektdiagramms reduziert.

In der folgenden Tabelle sind alle Verhalten des Paketzuschnitts zusammengefasst.The following table summarizes all the package pruning behaviors.

Anordnung von Abhängigkeiten Behavior
Entspricht der ID eines transitiven Pakets, das über ein anderes Paket kommt. Prune
Entspricht der ID eines transitiven Pakets, das durch ein anderes Projekt weitergeleitet wird. Prune
Entspricht der ID eines direkten PackageReference Wenden Sie PrivateAssets='all' und IncludeAssets='none' an und geben Sie die Warnung NU1510 aus, wenn das Paket aus allen Frameworks entfernt werden kann und das Projekt auf .NET 10 abzielt.
Entspricht der ID von ProjectReference Nicht zuschneiden und die NU1511-Warnung auslösen, wenn das Projekt auf .NET 10 ausgerichtet ist

PrunePackageReference-Anwendungen

Die Vorteile der Packungsschneidung sind zweifaltigen:

  • Leistungsvorteile durch Reduzierung der Anzahl von Paketen innerhalb eines Abhängigkeitsdiagramms
  • Reduzierung falsch positiver Ergebnisse durch Komponentenscanner wie NuGetAudit

Die Bereinigung ist besonders hilfreich, wenn Sie Pakete mitNuGetAuditMode festgelegter Einstellung allüberwachen. Wenn Sie .NET 9 verwenden, empfiehlt es sich, die Bereinigung durch Festlegen RestoreEnablePackagePruning auf true.