PackageReference dalam file proyek

Referensi paket, menggunakan <PackageReference> item MSBuild, menentukan dependensi paket NuGet langsung dalam file proyek, dibandingkan dengan memiliki file terpisah packages.config . Penggunaan PackageReference tidak memengaruhi aspek NuGet lainnya; misalnya, pengaturan dalam NuGet.Config file (termasuk sumber paket) masih diterapkan seperti yang dijelaskan dalam konfigurasi NuGet Umum.

Dengan PackageReference, Anda juga dapat menggunakan kondisi MSBuild untuk memilih referensi paket per kerangka kerja target, atau pengelompokan lainnya. Ini juga memungkinkan kontrol terperinci atas dependensi dan aliran konten. (Lihat Untuk detail selengkapnyaPaket dan pemulihan NuGet sebagai target MSBuild.)

Dukungan jenis proyek

Secara default, PackageReference digunakan untuk proyek .NET Core, proyek .NET Standard, dan proyek UWP yang menargetkan Windows 10 Build 15063 (Creators Update) dan yang lebih baru, dengan pengecualian proyek C++ UWP. Proyek .NET Framework mendukung PackageReference, tetapi saat ini default ke packages.config. Untuk menggunakan PackageReference, migrasikan dependensi dari packages.config ke file proyek Anda, lalu hapus packages.config.

ASP.NET aplikasi yang menargetkan .NET Framework lengkap hanya menyertakan dukungan terbatas untuk PackageReference. Jenis proyek C++ dan JavaScript tidak didukung.

Menambahkan PackageReference

Tambahkan dependensi dalam file proyek Anda menggunakan sintaks berikut:

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

Mengontrol versi dependensi

Konvensi untuk menentukan versi paket sama seperti saat menggunakan packages.config:

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

Dalam contoh di atas, 3.6.0 berarti versi apa pun yang = >3.6.0 dengan preferensi untuk versi terendah, seperti yang dijelaskan pada Penerapan versi Paket.

Menggunakan PackageReference untuk proyek tanpa dependensi paket

Tingkat Lanjut: Jika Anda tidak memiliki paket yang diinstal dalam proyek (tidak ada PackageReferences dalam file proyek dan tidak ada file packages.config), tetapi ingin proyek dipulihkan sebagai gaya PackageReference, Anda dapat mengatur properti Proyek RestoreProjectStyle ke PackageReference dalam file proyek Anda.

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

Ini mungkin berguna, jika Anda mereferensikan proyek yang ditata PackageReference (proyek gaya csproj atau SDK yang ada). Ini akan memungkinkan paket yang dirujuk oleh proyek tersebut, menjadi "transitif" yang dirujuk oleh proyek Anda.

PackageReference dan sumber

Dalam proyek PackageReference, versi dependensi transitif diselesaikan pada waktu pemulihan. Dengan demikian, dalam proyek PackageReference semua sumber harus tersedia untuk semua pemulihan.

Versi Mengambang

Versi mengambang didukung dengan PackageReference:

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

Mengontrol aset dependensi

Anda mungkin menggunakan dependensi murni sebagai harness pengembangan dan mungkin tidak ingin mengeksposnya ke proyek yang akan mengonsumsi paket Anda. Dalam skenario ini, Anda dapat menggunakan PrivateAssets metadata untuk mengontrol perilaku ini.

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

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

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

Tag metadata berikut mengontrol aset dependensi:

Tag Deskripsi Nilai Default
IncludeAssets Aset ini akan dikonsumsi all
ExcludeAssets Aset ini tidak akan digunakan tidak ada
PrivateAssets Aset ini akan digunakan tetapi tidak akan mengalir ke proyek induk contentfiles; Analisis; Membangun

Nilai yang diizinkan untuk tag ini adalah sebagai berikut, dengan beberapa nilai dipisahkan oleh titik koma kecuali dengan all dan none yang harus muncul sendiri:

Nilai Deskripsi
bangun lib Konten folder dan kontrol apakah proyek Anda dapat dikompilasi terhadap rakitan dalam folder
runtime lib Konten folder dan runtimes serta kontrol apakah rakitan ini akan disalin ke direktori output build
contentFiles contentfiles Isi folder
build .props dan .targets di build folder
buildMultitargeting (4.0).props dan .targets di buildMultitargeting folder, untuk penargetan lintas kerangka kerja
buildTransitive (5.0+).props dan .targets di buildTransitive folder , untuk aset yang mengalir secara transitif ke proyek apa pun yang mengkonsumsi. Lihat halaman fitur.
Analisis Penganalisis.NET
native native Isi folder
tidak ada Tidak ada hal di atas yang digunakan.
all Semua hal di atas (kecuali 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>

Perhatikan bahwa karena build tidak disertakan dengan PrivateAssets, target dan alat peraga akan mengalir ke proyek induk. Pertimbangkan, misalnya, bahwa referensi di atas digunakan dalam proyek yang membangun paket NuGet yang disebut AppLogger. AppLogger dapat menggunakan target dan alat peraga dari Contoso.Utility.UsefulStuff, seperti halnya proyek yang menggunakan AppLogger.

Catatan

Ketika developmentDependency diatur ke true dalam .nuspec file, ini menandai paket sebagai dependensi khusus pengembangan, yang mencegah paket disertakan sebagai dependensi dalam paket lain. Dengan PackageReference (NuGet 4.8+), bendera ini juga berarti bahwa bendera ini akan mengecualikan aset waktu kompilasi dari kompilasi. Untuk informasi selengkapnya, lihat Dukungan DevelopmentDependency untuk PackageReference.

Menambahkan kondisi PackageReference

Anda dapat menggunakan kondisi untuk mengontrol apakah paket disertakan, di mana kondisi dapat menggunakan variabel MSBuild atau variabel yang ditentukan dalam file target atau alat peraga. Namun, saat ini, hanya variabel yang TargetFramework didukung.

Misalnya, Anda menargetkan netstandard1.4 serta net452 tetapi memiliki dependensi yang hanya berlaku untuk net452. Dalam hal ini, Anda tidak ingin netstandard1.4 proyek yang menggunakan paket Anda untuk menambahkan dependensi yang tidak perlu tersebut. Untuk mencegah hal ini, Anda menentukan kondisi pada PackageReference sebagai berikut:

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

Paket yang dibangun menggunakan proyek ini akan menunjukkan bahwa Newtonsoft.Json disertakan sebagai dependensi hanya untuk net452 target:

The result of applying a Condition on PackageReference with VS2017

Kondisi juga dapat diterapkan pada tingkat dan ItemGroup akan berlaku untuk semua elemen anak PackageReference :

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

GeneratePathProperty

Fitur ini tersedia dengan NuGet 5.0 atau lebih tinggi dan dengan Visual Studio 2019 16.0 atau lebih tinggi.

Terkadang diinginkan untuk mereferensikan file dalam paket dari target MSBuild. Dalam packages.config proyek berbasis, paket diinstal dalam folder relatif terhadap file proyek. Namun dalam PackageReference, paket dikonsumsi dari folder paket global, yang dapat bervariasi dari komputer ke komputer.

Untuk menjemput kesenjangan itu, NuGet memperkenalkan properti yang menunjuk ke lokasi tempat paket akan digunakan.

Contoh:

  <ItemGroup>
      <PackageReference Include="Some.Package" Version="1.0.0" GeneratePathProperty="true" />
  </ItemGroup>

  <Target Name="TakeAction" AfterTargets="Build">
    <Exec Command="$(PkgSome_Package)\something.exe" />
  </Target>

Selain itu NuGet akan secara otomatis menghasilkan properti untuk paket yang berisi folder alat.

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

Properti MSBuild dan identitas paket tidak memiliki batasan yang sama sehingga identitas paket perlu diubah ke nama ramah MSBuild, diawali dengan kata Pkg. Untuk memverifikasi nama properti yang dihasilkan, lihat file nuget.g.props yang dihasilkan.

Alias PackageReference

Dalam beberapa instans langka, paket yang berbeda akan berisi kelas di namespace yang sama. Dimulai dengan NuGet 5.7 & Visual Studio 2019 Update 7, setara dengan ProjectReference, PackageReference mendukung Aliases. Secara default tidak ada alias yang disediakan. Ketika alias ditentukan, semua rakitan yang berasal dari paket anotasi dengan perlu dirujuk dengan alias.

Anda dapat melihat penggunaan sampel di NuGet\Samples

Dalam file proyek, tentukan alias sebagai berikut:

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

dan dalam kode gunakan sebagai berikut:

extern alias ExampleAlias;

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

Peringatan dan kesalahan NuGet

Fitur ini tersedia dengan NuGet 4.3 atau lebih tinggi dan dengan Visual Studio 2017 15.3 atau lebih tinggi.

Untuk banyak skenario paket dan pemulihan, semua peringatan dan kesalahan NuGet dikodekan, dan dimulai dengan NU****. Semua peringatan dan kesalahan NuGet tercantum dalam dokumentasi referensi .

NuGet mengamati properti peringatan berikut:

  • TreatWarningsAsErrors, perlakukan semua peringatan sebagai kesalahan
  • WarningsAsErrors, perlakukan peringatan tertentu sebagai kesalahan
  • NoWarn, sembunyikan peringatan tertentu, baik di seluruh proyek atau di seluruh paket.

Contoh:

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

Menekan peringatan NuGet

Meskipun disarankan agar Anda menyelesaikan semua peringatan NuGet selama operasi paket dan pemulihan Anda, dalam situasi tertentu yang menekannya dijaga. Untuk menekan luas proyek peringatan, pertimbangkan untuk melakukan:

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

Terkadang peringatan hanya berlaku untuk paket tertentu dalam grafik. Kita dapat memilih untuk menekan peringatan tersebut secara lebih selektif dengan menambahkan NoWarn pada item PackageReference.

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

Menekan peringatan paket NuGet di Visual Studio

Saat berada di Visual Studio, Anda juga dapat menekan peringatan melalui IDE.

Mengunci dependensi

Fitur ini tersedia dengan NuGet 4.9 atau lebih tinggi dan dengan Visual Studio 2017 15.9 atau lebih tinggi.

Input ke pemulihan NuGet adalah sekumpulan PackageReference item dari file proyek (dependensi tingkat atas atau langsung) dan outputnya adalah penutupan penuh dari semua dependensi paket termasuk dependensi transitif. NuGet mencoba untuk selalu menghasilkan penutupan penuh dependensi paket yang sama jika daftar PackageReference input tidak berubah. Namun, ada beberapa skenario di mana ia tidak dapat melakukannya. Contohnya:

  • Saat Anda menggunakan versi mengambang seperti <PackageReference Include="My.Sample.Lib" Version="4.*"/>. Meskipun niat di sini adalah untuk mengambang ke versi terbaru pada setiap pemulihan paket, ada skenario di mana pengguna mengharuskan grafik dikunci ke versi terbaru tertentu dan mengambang ke versi yang lebih baru, jika tersedia, dengan gerakan eksplisit.

  • Versi yang lebih baru dari persyaratan versi PackageReference yang cocok diterbitkan. Mis.

    • Hari 1: jika Anda menentukan <PackageReference Include="My.Sample.Lib" Version="4.0.0"/> tetapi versi yang tersedia di repositori NuGet adalah 4.1.0, 4.2.0 dan 4.3.0. Dalam hal ini, NuGet akan diselesaikan ke 4.1.0 (versi minimum terdekat)

    • Hari 2: Versi 4.0.0 akan diterbitkan. NuGet sekarang akan menemukan kecocokan yang tepat dan mulai menyelesaikan ke 4.0.0

  • Versi paket tertentu dihapus dari repositori. Meskipun nuget.org tidak mengizinkan penghapusan paket, tidak semua repositori paket memiliki batasan ini. Ini menghasilkan NuGet menemukan kecocokan terbaik ketika tidak dapat mengatasi versi yang dihapus.

Mengaktifkan file kunci

Untuk mempertahankan penutupan penuh dependensi paket, Anda dapat ikut serta ke fitur file kunci dengan mengatur properti RestorePackagesWithLockFile MSBuild untuk proyek Anda:

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

Jika properti ini diatur, pemulihan NuGet akan menghasilkan file kunci - packages.lock.json file di direktori akar proyek yang mencantumkan semua dependensi paket.

Catatan

Setelah proyek memiliki packages.lock.json file di direktori akarnya, file kunci selalu digunakan dengan pemulihan meskipun properti RestorePackagesWithLockFile tidak diatur. Jadi cara lain untuk ikut serta dalam fitur ini adalah dengan membuat file kosong packages.lock.json dummy di direktori akar proyek.

restore perilaku dengan file kunci

Jika file kunci ada untuk proyek, NuGet menggunakan file kunci ini untuk menjalankan restore. NuGet melakukan pemeriksaan cepat untuk melihat apakah ada perubahan dalam dependensi paket seperti yang disebutkan dalam file proyek (atau file proyek dependen) dan jika tidak ada perubahan, itu hanya memulihkan paket yang disebutkan dalam file kunci. Tidak ada evaluasi ulang dependensi paket.

Jika NuGet mendeteksi perubahan dependensi yang ditentukan seperti yang disebutkan dalam file proyek, NuGet mengevaluasi kembali grafik paket dan memperbarui file kunci untuk mencerminkan penutupan paket baru untuk proyek.

Untuk CI/CD dan skenario lainnya, di mana Anda tidak ingin mengubah dependensi paket dengan cepat, Anda dapat melakukannya dengan mengatur lockedmode ke true:

Untuk dotnet.exe, jalankan:

> dotnet.exe restore --locked-mode

Untuk msbuild.exe, jalankan:

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

Anda juga dapat mengatur properti MSBuild kondisi ini dalam file proyek Anda:

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

Jika mode terkunci adalah true, pemulihan akan memulihkan paket yang tepat seperti yang tercantum dalam file kunci atau gagal jika Anda memperbarui dependensi paket yang ditentukan untuk proyek setelah file kunci dibuat.

Jadikan kunci file bagian dari repositori sumber Anda

Jika Anda membangun aplikasi, yang dapat dieksekusi dan proyek yang dimaksud adalah pada awal rantai dependensi, maka periksa file kunci ke repositori kode sumber sehingga NuGet dapat menggunakannya selama pemulihan.

Namun, jika proyek Anda adalah proyek pustaka yang tidak Anda kirim atau proyek kode umum yang bergantung pada proyek lain, Anda tidak boleh memeriksa file kunci sebagai bagian dari kode sumber Anda. Tidak ada salahnya menyimpan file kunci tetapi dependensi paket terkunci untuk proyek kode umum mungkin tidak digunakan, seperti yang tercantum dalam file kunci, selama pemulihan/build proyek yang bergantung pada proyek kode umum ini.

Mis.

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

Jika ProjectA memiliki dependensi pada PackageX versi 2.0.0 dan juga referensi ProjectB yang bergantung pada PackageX versi 1.0.0, maka file kunci untuk ProjectB akan mencantumkan dependensi pada PackageX versi 1.0.0. Namun, ketika ProjectA dibangun, file kuncinya akan berisi dependensi pada PackageX versi 2.0.0 dan tidak1.0.0 seperti yang tercantum dalam file kunci untuk ProjectB. Dengan demikian, file kunci proyek kode umum memiliki sedikit ucapan atas paket yang diselesaikan untuk proyek yang bergantung padanya.

Mengunci ekstensibilitas file

Anda dapat mengontrol berbagai perilaku pemulihan dengan file kunci seperti yang dijelaskan di bawah ini:

opsi NuGet.exe opsi dotnet Opsi setara MSBuild Deskripsi
-UseLockFile --use-lock-file RestorePackagesWithLockFile Memilih penggunaan file kunci.
-LockedMode --locked-mode RestoreLockedMode Mengaktifkan mode terkunci untuk pemulihan. Ini berguna dalam skenario CI/CD di mana Anda menginginkan build yang dapat diulang.
-ForceEvaluate --force-evaluate RestoreForceEvaluate Opsi ini berguna dengan paket dengan versi mengambang yang ditentukan dalam proyek. Secara default, pemulihan NuGet tidak akan memperbarui versi paket secara otomatis pada setiap pemulihan kecuali Anda menjalankan pemulihan dengan opsi ini.
-LockFilePath --lock-file-path NuGetLockFilePath Menentukan lokasi file kunci kustom untuk proyek. Secara default, NuGet mendukung packages.lock.json di direktori akar. Jika Anda memiliki beberapa proyek dalam direktori yang sama, NuGet mendukung file kunci spesifik proyek packages.<project_name>.lock.json

AssetTargetFallback

Properti ini AssetTargetFallback memungkinkan Anda menentukan versi kerangka kerja tambahan yang kompatibel untuk proyek yang dirujuk proyek dan paket NuGet yang digunakan proyek Anda.

Jika Anda menentukan dependensi paket menggunakan PackageReference tetapi paket tersebut AssetTargetFallback tidak berisi aset yang kompatibel dengan kerangka kerja target proyek Anda, properti akan mulai dimainkan. Kompatibilitas paket yang direferensikan diperiksa ulang menggunakan setiap kerangka kerja target yang ditentukan dalam AssetTargetFallback. project Ketika atau dirujuk package melalui AssetTargetFallback, peringatan NU1701 akan dinaikkan.

Lihat tabel di bawah ini untuk contoh bagaimana AssetTargetFallback memengaruhi kompatibilitas.

Kerangka kerja proyek AssetTargetFallback Kerangka kerja paket Hasil
.NET Framework 4.7.2 .NET Standar 2.0 .NET Standar 2.0
Aplikasi .NET Core 3.1 .NET Standard 2.0, .NET Framework 4.7.2 .NET Standar 2.0
Aplikasi .NET Core 3.1 .NET Framework 4.7.2 Tidak kompatibel, gagal dengan NU1202
Aplikasi .NET Core 3.1 net472; net471 .NET Framework 4.7.2 .NET Framework 4.7.2 dengan NU1701

Beberapa kerangka kerja dapat ditentukan menggunakan ; sebagai pemisah. Untuk menambahkan kerangka kerja fallback, Anda dapat melakukan hal berikut:

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

Anda dapat meninggalkan $(AssetTargetFallback) jika Anda ingin menimpa, alih-alih menambahkan ke nilai yang AssetTargetFallback ada.

Catatan

Jika Anda menggunakan proyek berbasis .NET SDK, nilai yang sesuai $(AssetTargetFallback) dikonfigurasi dan Anda tidak perlu mengaturnya secara manual.

$(PackageTargetFallback) adalah fitur sebelumnya yang mencoba mengatasi tantangan ini, tetapi pada dasarnya rusak dan tidak boleh digunakan. Untuk bermigrasi dari $(PackageTargetFallback) ke $(AssetTargetFallback), cukup ubah nama properti.