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. Użycie funkcji PackageReference nie ma wpływu na inne aspekty NuGet, na przykład ustawienia w plikach (w NuGet.Config tym źródła pakietów) są nadal stosowane zgodnie z opisem w artykule Typowe konfiguracje NuGet.

Za pomocą funkcji PackageReference można również użyć warunków MSBuild do wybierania odwołań do pakietów dla platformy docelowej lub innych grup. Umożliwia również precyzyjną kontrolę nad zależnościami i przepływem zawartości. (Aby uzyskać więcej informacji, NuGet pakiet i przywracanie jako obiekty docelowe MSBuild).

Obsługa typów Project

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

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

Dodawanie elementu 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 korzystania z 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 funkcji PackageReferences

Zaawansowane: jeśli nie masz pakietów zainstalowanych w projekcie (brak właściwości PackageReferences w pliku projektu i bez pliku packages.config), ale chcesz przywrócić projekt jako styl PackageReference, możesz ustawić właściwość Project RestoreProjectStyle na 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). Dzięki temu pakiety, do których odwołują się te projekty, będą "przechodnio", 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 w programie 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

Być może używasz zależności wyłącznie jako narzędzia programistycznego i nie chcesz uwidaczniać 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 Description Wartość domyślna
Uwzględnij zasoby Te zasoby będą używane all
Wykluczanie zasobów Te zasoby nie będą używane brak
Zasoby prywatne 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 wartości i allnone które muszą się pojawiać 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
kompilacja .propsi .targets w folderze build
buildMultitargeting (4.0).props i .targets w folderze buildMultitargeting dla elementów docelowych między strukturami
buildTransitive (5.0+).props i .targets w folderze buildTransitive dla 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.
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 element nie jest uwzględniony w PrivateAssetselementach , elementy 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 tworzy pakiet NuGet o nazwie AppLogger. Aplikacja AppLogger może korzystać z elementów docelowych i rekwizytów z poziomu programu , ponieważ może korzystać z Contoso.Utility.UsefulStuffaplikacji AppLogger.

Uwaga

Gdy developmentDependency parametr jest ustawiony true na wartość 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 funkcji PackageReference (NuGet 4.8 lub nowszej) ta flaga oznacza również, że wykluczy zasoby czasu kompilacji. Aby uzyskać więcej informacji, zobacz DevelopmentDependency support for PackageReference (Obsługa zależności w programie DevelopmentDependency dla elementu PackageReference).

Dodawanie warunku PackageReference

Można użyć warunku, aby kontrolować, 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 celujesz netstandard1.4 , ale net452 masz zależność, która ma zastosowanie tylko dla elementu net452. 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 mogą być również stosowane 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 wersji Visual Studio 2019 16.0 lub nowszej.

Czasami pożądane jest odwoływanie się do plików w pakiecie z obiektu docelowego 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ła właściwość wskazującą lokalizację, z której pakiet zostanie użyty.

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 NuGet automatycznie wygeneruje właściwości pakietów zawierających folder narzędzi.

  <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 właściwości 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 wersji NuGet 5.7 & Visual Studio 2019 Update 7, co odpowiada funkcji ProjectReference, usługa PackageReference obsługuje funkcję Aliases. Domyślnie nie są udostępniane żadne aliasy. 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ć na stronie 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}");
        }
...
}

NuGet ostrzeżenia i błędy

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

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

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, ukrywa 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ń NuGet

Chociaż zaleca się rozwiązanie wszystkich ostrzeżeń NuGet podczas operacji pakowania i przywracania, w niektórych sytuacjach pomijanie ich 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 wykresie. 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 Visual Studio

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

Blokowanie zależności

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

Dane wejściowe do NuGet przywracania 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. NuGet próbuje zawsze utworzyć to samo pełne zamknięcie zależności pakietów, jeśli lista danych wejściowych PackageReference nie uległa zmianie. Istnieją jednak pewne scenariusze, w których nie można tego zrobić. Na przykład:

  • W przypadku korzystania z wersji zmiennoprzecinkowych, takich jak <PackageReference Include="My.Sample.Lib" Version="4.*"/>. Chociaż celem jest upłynięcie do najnowszej wersji przy każdym przywracaniu pakietów, istnieją scenariusze, w których użytkownicy wymagają zablokowania grafu do określonej najnowszej wersji i upłynięcia do nowszej wersji, jeśli jest dostępna, na jawnym gestie.

  • Opublikowano nowszą wersję pakietu zgodnego z wymaganiami dotyczącymi 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 NuGet zostałyby rozpoznane jako 4.1.0 (najbliższa minimalna wersja)

    • Dzień 2. Opublikowano wersję 4.0.0. NuGet będzie teraz znajdować dokładne dopasowanie i rozpocząć 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 NuGet znalezienie najlepszego dopasowania, gdy nie może rozpoznać usuniętej wersji.

Włączanie pliku blokady

Aby zachować pełne zamknięcie zależności pakietu, 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, NuGet przywracanie wygeneruje plik blokady — packages.lock.json plik w katalogu głównym projektu zawierający 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 za pomocą pliku blokady

Jeśli plik blokady jest obecny dla projektu, NuGet używa tego pliku blokady do uruchomienia polecenia restore. NuGet wykonuje szybką kontrolę, aby sprawdzić, czy w pliku projektu (lub plikach projektów zależnych) wystąpiły jakiekolwiek zmiany, a jeśli nie wprowadzono żadnych zmian, po prostu przywraca pakiety wymienione w pliku blokady. Nie ma ponownej oceny zależności pakietów.

Jeśli NuGet wykryje zmianę zdefiniowanych zależności, jak wspomniano w plikach projektu, program ponownie ocenia graf pakietu i aktualizuje 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 pakietu na bieżąco, możesz to zrobić, ustawiając wartość na lockedmodetrue:

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ę właściwość warunkową 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 w przypadku zaktualizowania zdefiniowanych 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 problem, 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ł z niego korzystać podczas przywracania.

Jeśli jednak projekt jest projektem biblioteki, od którego nie wysyłasz, lub typowym projektem 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 przechowywaniu pliku blokady, ale zablokowane zależności pakietu 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 istnieje zależność od PackageX wersji 2.0.0 , a także odwołuje ProjectB się do PackageX wersji 1.0.0, plik blokady dla ProjectB programu wyświetli zależność od PackageX wersji 1.0.0. Jednak podczas ProjectA kompilacji 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 rozwiązanych 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 opcja dotnet opcja równoważna 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 chcesz powtarzalnych kompilacji.
-ForceEvaluate --force-evaluate RestoreForceEvaluate Ta opcja jest przydatna w przypadku pakietów z zmienną wersją zdefiniowaną w projekcie. Domyślnie przywracanie NuGet nie będzie automatycznie aktualizować wersji pakietu po każdym przywróceniu, chyba że zostanie uruchomione przywracanie za pomocą tej opcji.
-LockFilePath --lock-file-path NuGetLockFilePath Definiuje niestandardową lokalizację pliku blokady dla projektu. Domyślnie NuGet obsługuje packages.lock.json katalog główny. Jeśli masz wiele projektów w tym samym katalogu, NuGet obsługuje plik blokady specyficzny dla projektupackages.<project_name>.lock.json

AssetTargetFallback

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

Jeśli określisz zależność pakietu przy użyciu polecenia PackageReference , ale ten pakiet nie zawiera zasobów, które są zgodne ze strukturą docelową projektu, AssetTargetFallback właściwość wchodzi w grę. 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 AssetTargetFallbackelementu zostanie zgłoszone ostrzeżenie NU1701 .

Zapoznaj się z poniższą tabelą, aby zapoznać się z AssetTargetFallback przykładami wpływu na zgodność.

struktura Project AssetTargetFallback Struktury pakietów Wynik
.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 zNU1701

Można określić wiele struktur przy użyciu ; 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ć, możesz pozostawić wartość off $(AssetTargetFallback) , zamiast dodawać do istniejących AssetTargetFallback wartości.

Uwaga

Jeśli używasz projektu opartego na zestawie .NET SDK, skonfigurowane są odpowiednie $(AssetTargetFallback) wartości 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) programu do $(AssetTargetFallback), po prostu zmień nazwę właściwości.