Udostępnij za pomocą


PackageReference w plikach projektu

Odwołania do pakietów, używając <PackageReference> elementów MSBuild, określają zależności pakietów NuGet bezpośrednio w plikach projektu, w przeciwieństwie do oddzielnego packages.config pliku. Korzystanie z funkcji PackageReference nie wpływa na inne aspekty narzędzia NuGet. Na przykład ustawienia w plikach NuGet.Config, w tym źródła pakietów, są nadal stosowane zgodnie z wyjaśnieniem w dokumencie Typowe konfiguracje NuGet.

Za pomocą funkcji PackageReference można również użyć warunków programu MSBuild, aby wybrać odwołania do pakietów dla docelowych platform oraz innych grupowań. Umożliwia również precyzyjną kontrolę nad zależnościami i przepływem zawartości. (Aby uzyskać więcej informacji, zobacz Pakiet NuGet i przywracanie jako obiekty docelowe programu MSBuild).

Obsługa typów projektów

Domyślnie funkcja PackageReference jest używana w projektach .NET, projektach .NET Standard i projektach platformy UWP przeznaczonych dla systemu Windows 10 Build 15063 (aktualizacja dla twórców) i nowszych, z wyjątkiem projektów platformy UWP języka C++. Projekty programu .NET Framework obsługują metodę PackageReference, ale obecnie domyślnie jest to packages.configwartość . Aby użyć funkcji PackageReference w projekcie programu .NET Framework, zmigruj zależności z packages.config pliku projektu, a następnie usuń packages.config.

ASP.NET aplikacje przeznaczone dla pełnego programu .NET Framework obejmują tylko ograniczoną obsługę funkcji PackageReference. Typy projektów C++ i JavaScript nie są obsługiwane.

Dodawanie funkcji PackageReference

Dodaj zależność w pliku projektu przy użyciu następującej składni:

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

Kontrolowanie wersji zależności

Konwencja określania wersji pakietu jest taka sama jak przy użyciu packages.config:

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

W powyższym przykładzie wersja 3.6.0 oznacza dowolną wersję >= 3.6.0 z preferencjami dla najniższej wersji, zgodnie z opisem w temacie Przechowywanie wersji pakietu.

Używanie funkcji PackageReference dla projektu bez zależności pakietów

Zaawansowane: jeśli w projekcie nie zainstalowano żadnych pakietów (brak funkcji PackageReferences w pliku projektu i brak pliku packages.config), ale chcesz przywrócić projekt jako styl PackageReference, możesz ustawić właściwość Project RestoreProjectStyle na wartość PackageReference w pliku projektu.

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

Może to być przydatne, jeśli odwołujesz się do projektów w stylu PackageReference (istniejące projekty w stylu csproj lub SDK). Umożliwi to, aby pakiety, do których odnoszą się te projekty, były również "przez translatywność" odwoływane przez Twój projekt.

PackageReference i źródła

W projektach PackageReference wersje zależności przechodnich są rozwiązywane w czasie przywracania. W związku z tym w projektach PackageReference wszystkie źródła muszą być dostępne dla wszystkich przywracania.

Wersje zmiennoprzecinkowe

Wersje dynamiczne są obsługiwane w:

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

Zarządzanie zależnościami zasobów

Może używasz zależności wyłącznie jako narzędzia do programowania i nie chcesz, aby była widoczna w projektach, które będą korzystać z twojego pakietu. W tym scenariuszu można użyć metadanych PrivateAssets do kontrolowania tego zachowania.

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

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

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

Następujące tagi metadanych kontrolują zasoby zależności:

Tag Description Wartość domyślna
IncludeAssets Te zasoby zostaną zużyte all
ExcludeAssets Te zasoby nie zostaną zużyte none
PrivateAssets Te zasoby będą używane, ale nie będą przepływać do projektu nadrzędnego contentfiles;analyzers;build

Dozwolone wartości dla tych tagów są następujące, z wieloma wartościami rozdzielonymi średnikami z wyjątkiem all i none, które muszą się pojawiać samodzielnie:

Value Description
kompilować Zawartość folderu lib i kontroluje, czy Twój projekt może zostać skompilowany względem zestawów w tym folderze.
środowisko uruchomieniowe Zawartość folderów lib i runtimes oraz kontrola, czy te zestawy zostaną skopiowane do katalogu wyjściowego kompilacji
contentFiles Zawartość folderu contentfiles
kompilacja .props i .targets w folderze build
buildMultitargeting (4.0).props i .targets w folderze buildMultitargeting, do określania celów dla wielu platform.
buildTransitive (5.0+) i w folderze , dla zasobów, które przepływają przechodnio do dowolnego projektu konsumenckiego. Zobacz stronę funkcjonalności.
analyzers Analizatory platformy .NET
macierzysty Zawartość folderu native
none Żaden z powyższych elementów nie jest używany.
all Wszystkie powyższe (z wyjątkiem 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>

Należy pamiętać, że ponieważ build nie jest uwzględniony wraz z PrivateAssets, cele i rekwizyty będą przepływać do projektu nadrzędnego. Rozważmy na przykład, że powyższe odwołanie jest używane w projekcie, który kompiluje pakiet NuGet o nazwie AppLogger. Aplikacja AppLogger może korzystać z elementów docelowych i rekwizytów z programu , ponieważ może korzystać z Contoso.Utility.UsefulStuffaplikacji AppLogger.

Note

Gdy developmentDependency parametr jest ustawiony na true w .nuspec pliku, oznacza to pakiet jako zależność tylko do programowania, która uniemożliwia dołączanie pakietu jako zależność w innych pakietach. W przypadku elementu PackageReference (NuGet 4.8 lub nowszego)ta flaga oznacza również, że wykluczy zasoby czasu kompilacji z kompilacji. Aby uzyskać więcej informacji, zobacz Obsługa współzależności dla elementu PackageReference.

Dodawanie warunku dla PackageReference

Możesz użyć warunku, aby określić, czy pakiet jest dołączony. Warunki mogą używać dowolnej zmiennej MSBuild lub zmiennej zdefiniowanej w pliku obiektów docelowych lub props. Jednak obecnie obsługiwana jest tylko zmienna TargetFramework .

Załóżmy na przykład, że jest to element docelowy netstandard1.4 , a także net452 zależność, która ma zastosowanie tylko dla net452elementu . W takim przypadku nie chcesz netstandard1.4 , aby projekt korzystający z pakietu dodał tę niepotrzebną zależność. Aby temu zapobiec, należy określić warunek na PackageReference w sposób następujący:

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

Pakiet utworzony przy użyciu tego projektu pokaże, że Newtonsoft.Json jest uwzględniony jako zależność tylko dla net452 docelowego.

Wynik zastosowania warunku na elemencie PackageReference przy użyciu Visual Studio 2017

Warunki można również zastosować na poziomie ItemGroup i będą stosowane do wszystkich elementów podrzędnych PackageReference.

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

GeneratePathProperty

Ta funkcja jest dostępna w wersji NuGet 5.0 lub nowszej oraz w programie Visual Studio 2019 16.0 lub nowszym.

Czasami pożądane jest odwołanie do plików w pakiecie z docelowego programu MSBuild. W projektach opartych na packages.config dane pakiety są instalowane w folderze względnie do pliku projektu. Jednak w elemencie PackageReference pakiety są wykorzystywane z folderu global-packages, którego lokalizacja może się różnić na różnych komputerach.

Aby wypełnić tę lukę, NuGet wprowadził właściwość wskazującą lokalizację, z której zostanie użyty pakiet.

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>

Ponadto narzędzie NuGet automatycznie generuje właściwości pakietów zawierających folder tools.

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

Właściwości programu MSBuild i tożsamości pakietów nie mają tych samych ograniczeń, więc tożsamość pakietu musi zostać zmieniona na nazwę przyjazną dla MSBuild, poprzedzoną słowem Pkg. Aby sprawdzić dokładną nazwę wygenerowanej właściwości, należy spojrzeć na wygenerowany plik nuget.g.props.

Aliasy packageReference

W niektórych rzadkich przypadkach różne pakiety będą zawierać klasy w tej samej przestrzeni nazw. Począwszy od NuGet 5.7 i Visual Studio 2019 Update 7, analogicznie do ProjectReference, PackageReference obsługuje Aliases. Domyślnie nie podano aliasów. Po określeniu aliasu wszystkie zestawy pochodzące z pakietu z adnotacjami muszą być przywoływane z aliasem.

Przykładowe użycie można sprawdzić w witrynie NuGet\Samples.

W pliku projektu określ aliasy w następujący sposób:

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

W kodzie użyj go w następujący sposób:

extern alias ExampleAlias;

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

Ostrzeżenia i błędy narzędzia NuGet

Ta funkcja jest dostępna w programie NuGet 4.3 lub nowszym oraz w programie Visual Studio 2017 15.3 lub nowszym.

W przypadku wielu scenariuszy pakowania i przywracania wszystkie ostrzeżenia i błędy NuGet są kodowane i zaczynają się od NU****. Wszystkie ostrzeżenia i błędy narzędzia NuGet są wymienione w dokumentacji referencyjnej.

Program NuGet obserwuje następujące właściwości ostrzeżenia:

  • TreatWarningsAsErrors, traktuj wszystkie ostrzeżenia jako błędy.
  • WarningsAsErrors, traktuj określone ostrzeżenia jako błędy.
  • NoWarn, ukryj określone ostrzeżenia, w całym projekcie lub w całym pakiecie.

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>

Pomijanie ostrzeżeń narzędzia NuGet

Chociaż zaleca się rozwiązanie wszystkich ostrzeżeń narzędzia NuGet podczas operacji pakowania i przywracania, w niektórych sytuacjach ich pominięcie może być uzasadnione. Aby stłumić ostrzeżenie w całym projekcie, rozważ wykonanie następujących czynności:

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

Czasami ostrzeżenia dotyczą tylko określonego pakietu na grafie. Możesz pominąć to ostrzeżenie bardziej selektywnie, dodając element NoWarn PackageReference.

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

Pomijanie ostrzeżeń pakietu NuGet w programie Visual Studio

W programie Visual Studio można również pominąć ostrzeżenia za pośrednictwem środowiska IDE.

Blokowanie zależności

Ta funkcja jest dostępna w programie NuGet 4.9 lub nowszym oraz w programie Visual Studio 2017 15.9 lub nowszym.

Dane wejściowe do przywracania NuGet to zestaw elementów z pliku projektu (górnego poziomu lub bezpośrednich zależności), a dane wyjściowe obejmują pełne spektrum wszystkich zależności pakietu, w tym zależności przechodnie. Program NuGet próbuje zawsze utworzyć to samo pełne zamknięcie zależności pakietów, jeśli lista input PackageReference nie uległa zmianie. Istnieją jednak pewne scenariusze, w których nie można tego zrobić. Przykład:

  • Kiedy używasz wersji pływających, takich jak <PackageReference Include="My.Sample.Lib" Version="4.*"/>. Chociaż w tym przypadku celem jest przejście na najnowszą wersję przy każdym przywracaniu pakietów, istnieją scenariusze, w których użytkownicy wymagają zablokowania grafu do określonej najnowszej wersji i przejścia do nowszej wersji, jeśli jest dostępna, po wyraźnym działaniu.

  • Opublikowano nowszą wersję pakietu pasującą do wymagań wersji PackageReference. Przykład:

    • Dzień 1: jeśli określono, <PackageReference Include="My.Sample.Lib" Version="4.0.0"/> ale wersje dostępne w repozytoriach NuGet to 4.1.0, 4.2.0 i 4.3.0. W takim przypadku pakiet NuGet rozpoznałby wersję 4.1.0 (najbliższą minimalną wersję).

    • Dzień 2. Opublikowano wersję 4.0.0. Narzędzie NuGet znajdzie teraz dokładne dopasowanie i rozpocznie rozpoznawanie do wersji 4.0.0.

  • Dana wersja pakietu jest usuwana z repozytorium. Chociaż nuget.org nie zezwala na usuwanie pakietów, nie wszystkie repozytoria pakietów mają to ograniczenie. To spowoduje, że NuGet znajdzie najlepsze dopasowanie, gdy nie może rozpoznać usuniętej wersji.

Włączanie pliku blokady

Aby zachować pełne zamknięcie zależności pakietów, możesz wyrazić zgodę na funkcję pliku blokady, ustawiając właściwość RestorePackagesWithLockFile MSBuild dla projektu:

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

Jeśli ta właściwość jest ustawiona, przywracanie NuGet wygeneruje plik blokady (packages.lock.json) w katalogu głównym projektu, który zawiera listę wszystkich zależności pakietu.

Note

Gdy projekt ma packages.lock.json plik w katalogu głównym, plik blokady jest zawsze używany z przywracaniem, nawet jeśli właściwość RestorePackagesWithLockFile nie jest ustawiona. Innym sposobem wyrażenia zgody na tę funkcję jest utworzenie pustego fikcyjnego pliku packages.lock.json w katalogu głównym projektu.

restore zachowanie z plikiem blokady

Jeśli plik blokady jest obecny dla projektu, nuGet używa tego pliku blokady do uruchomienia restore. Narzędzie NuGet umożliwia szybkie sprawdzenie, czy w pliku projektu (lub plikach projektów zależnych) wystąpiły jakiekolwiek zmiany w zależnościach pakietu, a jeśli nie nastąpiły żadne zmiany, po prostu przywraca pakiety wymienione w pliku blokady. Nie ma ponownej oceny zależności pakietów.

Jeśli program NuGet wykryje zmianę zdefiniowanych zależności, jak wspomniano w plikach projektu, ponownie oceni wykres pakietu i zaktualizuje plik blokady, aby odzwierciedlić nowe zamknięcie pakietu dla projektu.

W przypadku ciągłej integracji/ciągłego wdrażania i innych scenariuszy, w których nie chcesz zmieniać zależności pakietów dynamicznie, możesz to zrobić, ustawiając lockedmode na true.

W przypadku dotnet.exe uruchom:

> dotnet.exe restore --locked-mode

W przypadku msbuild.exe uruchom polecenie:

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

Tę warunkową właściwość MSBuild można również ustawić w pliku projektu:

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

Jeśli tryb zablokowany to true, przywracanie spowoduje odtworzenie dokładnie tych pakietów, które są wymienione w pliku blokady, albo zakończy się niepowodzeniem, jeśli po utworzeniu pliku blokady zaktualizowano zdefiniowane zależności pakietów dla projektu.

Blokowanie plików i narzędzie PrunePackageReference

Funkcja PrunePackageReference zmienia zależności projektu, usuwając niepotrzebne pakiety przejściowe. Usunięcie tych pakietów nie powinno mieć wpływu na środowisko uruchomieniowe, ale będzie miało wpływ na pliki blokady. Jeśli włączysz oczyszczanie istniejącego projektu, za każdym razem, gdy plik blokady zostanie wygenerowany ponownie, może to prowadzić do mniejszej liczby pakietów niż przed oczyszczeniem. Aktualizacja pliku blokady, która wspiera tryb blokowania, jest świadoma przycinania, co oznacza, że jeśli w projekcie włączono przycinanie, kontrola uwzględni pakiety, które zostały przycięte. Jednak następnym razem, gdy plik blokady zostanie ponownie wygenerowany, wykluczy oczyszczone pakiety, więc może być widoczna różnica, która jest większa niż zwykle.

Dodaj plik blokady do swojego repozytorium źródłowego

Jeśli tworzysz aplikację, plik wykonywalny i projekt, którego dotyczy, znajduje się na początku łańcucha zależności, sprawdź plik blokady w repozytorium kodu źródłowego, aby nuGet mógł korzystać z niego podczas przywracania.

Jeśli jednak projekt jest projektem biblioteki, który nie jest dostarczony lub wspólny projekt kodu, od którego zależą inne projekty, nie należy zaewidencjonować pliku blokady w ramach kodu źródłowego. Nie ma żadnych szkód w zachowaniu pliku blokady, ale zablokowane zależności pakietów dla wspólnego projektu kodu nie mogą być używane, jak pokazano w pliku blokady, podczas przywracania/kompilowania projektu, który zależy od tego wspólnego projektu kodu.

Example:

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

Jeśli ProjectA ma zależność od PackageX wersji 2.0.0 i również odwołuje się do ProjectB, który zależy od PackageX wersji 1.0.0, wtedy plik blokady dla ProjectB wykaże zależność od PackageX wersji 1.0.0. Jednak, gdy ProjectA zostanie skompilowany, jego plik blokady będzie zawierać zależność od PackageX w wersji 2.0.0, a nie jak wymieniono w pliku blokady dla 1.0.0. W związku z tym plik blokady we wspólnym projekcie kodu ma niewielki wpływ na pakiety rozstrzygane dla projektów, które od niego zależą.

Blokowanie rozszerzalności pliku

Możesz kontrolować różne zachowania przywracania za pomocą pliku blokady, jak opisano poniżej:

opcja NuGet.exe dotnet option (opcja dotnet) Opcja równoważna programu MSBuild Description
-UseLockFile --use-lock-file RestorePackagesWithLockFile Wyraża zgodę na użycie pliku blokady.
-LockedMode --locked-mode RestoreLockedMode Włącza tryb zablokowany na potrzeby przywracania. Jest to przydatne w scenariuszach ciągłej integracji/ciągłego wdrażania, w których mają być powtarzalne kompilacje.
-ForceEvaluate --force-evaluate RestoreForceEvaluate Ta opcja jest przydatna w przypadku pakietów z zmienną wersją zdefiniowaną w projekcie. Domyślnie przywracanie nuGet nie spowoduje automatycznej aktualizacji wersji pakietu po każdym przywróceniu, chyba że uruchomisz przywracanie za pomocą tej opcji.
-LockFilePath --lock-file-path NuGetLockFilePath Definiuje niestandardową lokalizację pliku blokady dla projektu. Domyślnie pakiet NuGet obsługuje packages.lock.json katalog główny. Jeśli masz wiele projektów w tym samym katalogu, pakiet NuGet obsługuje plik blokady specyficzny dla projektu packages.<project_name>.lock.json

Rozwiązanie zależności NuGet

Narzędzie rozpoznawania zależności NuGet jest zgodne z czterema regułami zgodnie z opisem w dokumencie rozpoznawania zależności.

Aby zwiększyć wydajność i skalowalność operacji przywracania, algorytm przywracania został przepisany w wersji 6.12. Od wersji 6.12 nowy algorytm przywracania jest domyślnie włączony dla wszystkich projektów PackageReference. Chociaż nowy algorytm przywracania jest funkcjonalnie odpowiednikiem poprzedniego, podobnie jak w przypadku dowolnego oprogramowania, możliwe są błędy. Aby przywrócić poprzednią implementację, ustaw właściwość MSBuild RestoreUseLegacyDependencyResolver na true.

Jeśli napotkasz błędy przywracania w wersji 6.12, .NET 9 lub 17.12, które nie były odtwarzane we wcześniejszych wersjach, zgłoś problem w usłudze GitHub. Wszelkie różnice między starymi i nowymi algorytmami mogą mieć różne skutki, takie jak podczas kompilacji lub w czasie wykonywania. Istnieje również prawdopodobieństwo, że zmiany nie prowadzą do błędów, ale są przywracane różne wersje pakietów. Jeśli uważasz, że może to mieć wpływ na jakiekolwiek zmiany, oto kroki, które można wykonać, aby sprawdzić, czy zmiany algorytmu przywracania NuGet są główną przyczyną.

Przywracanie zapisuje wyniki w MSBuildProjectExtensionsPath katalogu, które można porównać z nowymi i starymi algorytmami, aby znaleźć różnice. Zazwyczaj jest to folder obj twojej kompilacji. Możesz użyć msbuild.exe polecenia lub dotnet.exe w następnych krokach.

  1. Usuń folder o nazwie obj dla swojego projektu.

  2. Uruchom polecenie msbuild -t:restore

  3. Zapisz zawartość obj obiektu w lokalizacji wskazującej new , że jest to zachowanie.

  4. Uruchom program msbuild -t:restore -p:RestoreUseLegacyDependencyResolver="true".

  5. Zapisz zawartość obj obiektu w lokalizacji wskazującej new , że jest to zachowanie.

  6. Porównaj pliki w dwóch katalogach, szczególnie project.assets.json.

    Narzędzia, które mogą wyróżniać różnice, są szczególnie przydatne w tym przypadku (na przykład w programie Visual Studio Code otwórz oba pliki i użyj prawym przyciskiem myszy przycisku "wybierz do porównania" i "porównaj z wybranym").

Jeśli zastosujesz się do powyższej metody, powinna być dokładnie 1 różnica między plikami project.assets.json:

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

Jeśli pojawią się jeszcze jakieś różnice, proszę zgłosić problem na GitHubie wraz ze wszystkimi szczegółami.

AssetTargetFallback

Właściwość AssetTargetFallback umożliwia określenie dodatkowych zgodnych wersji frameworków dla projektów, do których odwołuje się Twój projekt, oraz pakietów NuGet używanych przez Twój projekt.

Jeśli określisz zależność pakietu za pomocą PackageReference, ale ten pakiet nie zawiera zasobów zgodnych z docelowym frameworkiem Twojego projektu, właściwość AssetTargetFallback zacznie odgrywać rolę. Zgodność przywoływanego pakietu jest ponownie zaznaczona przy użyciu każdej platformy docelowej określonej w elemencie AssetTargetFallback. Kiedy element project lub package jest odwoływany za pośrednictwem AssetTargetFallback, zostanie wygenerowane ostrzeżenie o numerze NU1701.

Odwołaj się do poniższej tabeli, aby zobaczyć przykłady, jak AssetTargetFallback wpływa na zgodność.

Struktura projektu AssetTargetFallback Struktury pakietów Result
.NET Framework 4.7.2 .NET Standard 2.0 .NET Standard 2.0
Aplikacja .NET Core 3.1 .NET Standard 2.0, .NET Framework 4.7.2 .NET Standard 2.0
Aplikacja .NET Core 3.1 .NET Framework 4.7.2 Niekompatybilne, błąd z NU1202
Aplikacja .NET Core 3.1 net472;net471 .NET Framework 4.7.2 .NET Framework 4.7.2 z NU1701

Można określić wiele struktur za pomocą ; ogranicznika. Aby dodać strukturę rezerwową, możesz wykonać następujące czynności:

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

Jeśli chcesz zastąpić istniejące wartości zamiast dodawać do nich, możesz pominąć $(AssetTargetFallback), aby nadpisać wartości AssetTargetFallback.

Note

Jeśli używasz projektu opartego na zestawie SDK platformy .NET, odpowiednie wartości są skonfigurowane i nie trzeba ich ustawiać ręcznie.

$(PackageTargetFallback) była wcześniejszą funkcją, która próbowała rozwiązać to wyzwanie, ale jest fundamentalnie wadliwa i nie powinna być używana. Aby przeprowadzić migrację z $(PackageTargetFallback) do $(AssetTargetFallback), po prostu zmień nazwę właściwości.

PrunePackageReference

Środowisko uruchomieniowe platformy .NET stale ewoluuje wraz z ulepszeniami wydajności i nowymi interfejsami API w każdej wersji. Nowe funkcje dodane do platformy .NET są również czasami udostępniane jako pakiety, dzięki czemu deweloperzy korzystający ze starszych platform docelowych mogą korzystać z biblioteki, takiej jak System.Text.Json. Często może to prowadzić do System.Text.Json 8.0.0 w projekcie przeznaczonym na .NET 9 lub .NET 8. Ta zależność jest niepotrzebna, a rozwiązywanie konfliktów podczas kompilacji nie będzie wykorzystywać zestawu z pakietu, ponieważ jest on już dostępny w środowisku uruchomieniowym .NET. Począwszy od NuGet w wersji 6.13 i .NET SDK 9.0.200, PrunePackageReference umożliwia oczyszczanie tych pakietów w czasie przywracania dla projektów opartych na .NET SDK. Pierwsza iteracja oczyszczania dotyczy tylko pakietów przechodnich, ale począwszy od zestawu .NET SDK 10, oczyszczanie pakietów wpływa również na pakiety bezpośrednie.

Oczyszczanie pakietów jest dostępne jako funkcja opt-in z zestawem SDK platformy .NET 9 i jest domyślnie włączona dla wszystkich struktur projektu przeznaczonego >= .NET 10.0 dla zestawu SDK platformy .NET 10.

Oczyszczanie pakietów jest dostępne tylko w przypadku domyślnego rozwiązania zależności, ponieważ został wydany w wersji 6.12.

Specyfikacja prunePackageReference

Lista pakietów do przycinania jest definiowana za pomocą elementu PrunePackageReference.

Attributes Description
Version Określa maksymalną wersję do przycinania. 1.0.0 oznacza, że wszystkie pakiety do 1.0.0 zostaną oczyszczone. W przypadku 1.0.00.9.0 i 1.0.0 zostaną przycinane, ale 1.0.1 nie.

Następujące właściwości mogą służyć do modyfikowania zachowania przycinania.

PropertyName Description
RestoreEnablePackagePruning Włącza oczyszczanie pakietów dla pakietów określonych przy użyciu PrunePackageReference. Ta właściwość jest przypisana do platformy docelowej, a prawidłowe wartości to true i false. Wartości domyślne mogą się różnić w zależności od zestawu .NET SDK zgodnie z definicją powyżej.

Zestaw SDK platformy .NET wstępnie określa listę pakietów, które mają zostać wyczyszczone.

Jak działa funkcja PrunePackageReference

Po określeniu pakietu, który ma zostać oczyszczony podczas przywracania, zostanie on usunięty z grafu zależności. Po oczyszczeniu pakietu jest wyświetlany komunikat widoczny w szczegółowej szczegółowości wskazujący, że pakiet został usunięty dla danej platformy docelowej.

W przypadku pakietów przechodnich, co oznacza zależności innych pakietów lub projektów, pakiety nie są pobierane i nie są wyświetlane w żadnym z danych wyjściowych narzędzia NuGet.

W przypadku bezpośrednich pakietów PrivateAssets='all' i IncludeAssets='none' są stosowane niejawnie.

  • IncludeAssets='none' zapewnia, że zestawy z tego pakietu nie są używane podczas kompilacji. Zanim istniało przycinanie, rozwiązanie konfliktu podczas kompilacji gwarantowało, że zestawy platform były preferowane nad zestawami pochodzącymi z pakietów.
  • PrivateAssets='all' zapobiega uwzględnianiu pakietów w innych pakietach lub przez odwołania do projektu.

Example:

Projekt podobny do poniższego:

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

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

program będzie mieć plik pakietu .nuspec z następującymi zależnościami:

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

Jeśli bezpośrednia funkcja PackageReference może zostać całkowicie usunięta z projektu, a jedna z platform projektów to .NET 10 lub nowsza, zostanie zgłoszony pakiet NU1510 z prośbą o usunięcie pakietu. Po wykonaniu tej sugestii zmniejszysz złożoność grafu projektu.

Poniższa tabela zawiera podsumowanie wszystkich zachowań przy usuwaniu pakietów.

Dyspozycja zależności Behavior
Dopasowuje identyfikator pakietu przechodniego wchodzącego przez inny pakiet Prune
Odpowiada identyfikatorowi pakietu przechodniego przechodzącego przez inny projekt Prune
Pasuje do bezpośredniego identyfikatora PackageReference Zastosuj PrivateAssets='all' i IncludeAssets='none' oraz zgłoś ostrzeżenie NU1510, gdy pakiet można usunąć ze wszystkich ram, a projekt jest przeznaczony dla platformy .NET 10.
Dopasowuje się do identyfikatora ProjectReference Nie przycinaj i zgłaszaj ostrzeżenie NU1511 , gdy projekt jest przeznaczony dla platformy .NET 10

Aplikacje PrunePackageReference

Zalety oczyszczania pakietów są dwojakie:

  • Korzyści z wydajności dzięki zmniejszeniu liczby pakietów w grafie zależności
  • Zmniejszenie liczby fałszywie dodatnich wyników przez skanery komponentów, na przykład NuGetAudit

Oczyszczanie jest szczególnie przydatne podczas inspekcji pakietów z NuGetAuditMode ustawionym na all. Jeśli używasz platformy .NET 9, zalecamy wypróbowanie oczyszczania, ustawiając wartość RestoreEnablePackagePruning .true