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 NuGet.Config plikach (w tym źródłach pakietów) są nadal stosowane zgodnie z wyjaśnieniem w temacie Typowe konfiguracje NuGet.

Za pomocą funkcji PackageReference można również użyć warunków programu MSBuild, aby wybrać odwołania do pakietów na strukturę docelową lub inne grupy. Umożliwia również precyzyjną kontrolę nad zależnościami i przepływem zawartości. (Zobacz Aby uzyskać więcej informacji 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 Core, 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, zmigruj zależności z packages.config pliku projektu, a następnie usuń plik 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 w przypadku używania polecenia 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 pakietom, do których odnoszą się te projekty, do których odwołuje się 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 zmiennoprzecinkowe są obsługiwane za pomocą polecenia PackageReference:

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

Kontrolowanie zasobów zależności

Może być używana zależność wyłącznie jako wykorzystanie programowania i może nie chcieć uwidocznić go w projektach, które będą korzystać z pakietu. W tym scenariuszu można użyć metadanych do kontrolowania PrivateAssets 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 opis Wartość domyślna
Uwzględnij zasoby Te zasoby zostaną zużyte wszystkie
Wykluczanie zasobów Te zasoby nie zostaną zużyte Brak
Zasoby prywatne Te zasoby będą używane, ale nie będą przepływać do projektu nadrzędnego contentfiles; Analizatory; Budować

Dozwolone wartości dla tych tagów są następujące, z wieloma wartościami oddzielonymi średnikami z wyjątkiem wartości i allnone które muszą być wyświetlane samodzielnie:

Wartość Opis
kompilowanie lib Zawartość folderu i określa, czy projekt może być kompilowany względem zestawów w folderze
środowisko uruchomieniowe lib Zawartość folderu i runtimes określa, czy te zestawy zostaną skopiowane do katalogu wyjściowego kompilacji
contentFiles contentfiles Zawartość folderu
build .propsi .targets w folderze build
buildMultitargeting (4.0).props i .targets w folderze buildMultitargeting dla określania wartości docelowych między strukturami
buildTransitive (5.0+).props i .targets w folderze buildTransitive w przypadku zasobów, które przepływają przechodnio do dowolnego projektu zużywanego. Zobacz stronę funkcji.
Analizatory Analizatory .NET
natywne native Zawartość folderu
Brak Żaden z powyższych elementów nie jest używany.
wszystkie 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 element docelowy i rekwizyty nie są uwzględniane w PrivateAssetsprojekcie nadrzędnym, obiekty docelowe 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.

Uwaga

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 DevelopmentDependency support for PackageReference (Obsługa współzależności dla elementu PackageReference).

Dodawanie warunku PackageReference

Można użyć warunku, aby określić, czy pakiet jest dołączony, gdzie 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 ona przeznaczona netstandard1.4 dla net452 elementu , ale ma 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 w PackageReference następujący sposób:

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

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

The result of applying a Condition on PackageReference with VS2017

Warunki można również zastosować na ItemGroup poziomie 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 packages.config projektach opartych pakiety są instalowane w folderze względem pliku projektu. Jednak w elemencie PackageReference pakiety są używane z folderu global-packages , który może się różnić od komputera do komputera.

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

Przykład:

  <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 pakiet NuGet automatycznie wygeneruje 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 przyjazną nazwę msBuild, poprzedzoną słowem Pkg. Aby sprawdzić dokładną nazwę wygenerowanej właściwości, przyjrzyj się wygenerowanemu plikowi 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 pakietów NuGet 5.7 i Visual Studio 2019 Update 7, co odpowiada usłudze ProjectReference, funkcja PackageReference obsługuje funkcję 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>

i 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 pakietów i przywracania wszystkie ostrzeżenia i błędy narzędzia 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.

Przykłady:

<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 pomijanie jest uzasadnione. Aby pominąć cały projekt ostrzegawczy, rozważ wykonanie następującej 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żemy 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 PackageReference elementów z pliku projektu (zależności najwyższego lub bezpośredniego), a dane wyjściowe są pełnym zamknięciem wszystkich zależności pakietu, w tym zależności przechodnich. 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ć. Na przykład:

  • W przypadku używania wersji zmiennoprzecinkowych, takich jak <PackageReference Include="My.Sample.Lib" Version="4.*"/>. Chociaż w tym przypadku celem jest zmiennoprzecinkowe do najnowszej wersji dla każdego przywracania pakietów, istnieją scenariusze, w których użytkownicy wymagają zablokowania grafu do określonej najnowszej wersji i przemieszczenia do nowszej wersji, jeśli jest dostępna, po jawnym gestzie.

  • Opublikowano nowszą wersję pakietu pasującą do wymagań wersji PackageReference. Na 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. Spowoduje to znalezienie najlepszego dopasowania narzędzia NuGet, 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 plik w katalogu głównym projektu, który zawiera listę wszystkich zależności pakietu.

Uwaga

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 fikcyjnego pustego packages.lock.json pliku w katalogu głównym projektu.

restore zachowanie przy użyciu pliku 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 na bieżąco, możesz to zrobić, ustawiając wartość na true:lockedmode

W przypadku dotnet.exe uruchom polecenie:

> 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 przywrócenie dokładnych pakietów wymienionych w pliku blokady lub niepowodzenie, jeśli zaktualizowano zdefiniowane zależności pakietu dla projektu po utworzeniu pliku blokady.

Utwórz część pliku blokady w repozytorium źródłowym

Jeśli tworzysz aplikację, plik wykonywalny i projekt, którego dotyczy pytanie, znajduje się na początku łańcucha zależności, następnie zaewidencjonuj 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 mogą nie być używane, jak pokazano w pliku blokady, podczas przywracania/kompilowania projektu, który zależy od tego wspólnego projektu kodu.

Na przykład:

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

Jeśli ProjectA ma zależność od PackageX wersji 2.0.0 , a także odwołuje ProjectB się do PackageX wersji 1.0.0, plik ProjectB blokady dla programu wyświetli zależność od PackageX wersji 1.0.0. Jednak gdy ProjectA zostanie skompilowany, jego plik blokady będzie zawierać zależność od PackageX wersji 2.0.0 , a nie1.0.0 jak pokazano w pliku blokady dla programu ProjectB. W związku z tym plik blokady wspólnego projektu kodu niewiele mówi o pakietach rozpoznawanych 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 opis
-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

AssetTargetFallback

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

Jeśli określisz zależność pakietu przy użyciu polecenia PackageReference , ale ten pakiet nie zawiera zasobów zgodnych ze strukturą docelową projektów, AssetTargetFallback właściwość zostanie w pełni uwzględniona. Zgodność przywoływanego pakietu jest ponownie zaznaczona przy użyciu każdej platformy docelowej określonej w elemencie AssetTargetFallback. W przypadku odwołania do elementu project lub package do elementu zostanie zgłoszone ostrzeżenie NU1701AssetTargetFallback.

Zapoznaj się z poniższą tabelą, aby zapoznać się z AssetTargetFallback przykładami wpływu 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 Niezgodne, niepowodzenie 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ć, zamiast dodawać do istniejących AssetTargetFallback wartości, możesz opuścić tę $(AssetTargetFallback) opcję.

Uwaga

Jeśli używasz projektu opartego na zestawie SDK platformy .NET, odpowiednie $(AssetTargetFallback) 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 zasadniczo uszkodzona i nie powinna być używana. Aby przeprowadzić migrację z $(PackageTargetFallback) do $(AssetTargetFallback), po prostu zmień nazwę właściwości.