Misalkan saya memiliki perpustakaan kelas yang saya ingin menargetkan netstandard1.3, tetapi juga menggunakan BigInteger
. Berikut adalah contoh sepele - satu-satunya file sumber adalah Adder.cs
:
using System;
using System.Numerics;
namespace Calculator
{
public class Adder
{
public static BigInteger Add(int x, int y)
=> new BigInteger(x) + new BigInteger(y);
}
}
Kembali ke dunia project.json
, saya akan menargetkan netstandard1.3
di frameworks
bagian, dan memiliki ketergantungan eksplisit pada System.Runtime.Numerics
, misalnya versi 4.0.1. Paket nuget yang saya buat hanya akan mencantumkan ketergantungan itu.
Dalam dunia baru yang berani berbasis csproj dotnet perkakas (Saya menggunakan v1.0.1 alat baris perintah) ada sebuah implisit paket metapackage referensi untuk NETStandard.Library 1.6.1
saat menargetkan netstandard1.3
. Ini berarti file proyek saya sangat kecil, karena tidak memerlukan ketergantungan eksplisit:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.3</TargetFramework>
</PropertyGroup>
</Project>
... tetapi paket nuget yang dihasilkan memiliki ketergantungan pada NETStandard.Library
, yang menunjukkan bahwa untuk menggunakan perpustakaan kecil saya, Anda memerlukan semua yang ada di sana.
Ternyata saya bisa menonaktifkan fungsionalitas itu menggunakan DisableImplicitFrameworkReferences
, lalu menambahkan dependensi secara manual lagi:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.3</TargetFramework>
<DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Runtime.Numerics" Version="4.0.1" />
</ItemGroup>
</Project>
Sekarang paket NuGet saya menjelaskan dengan tepat apa itu tergantung. Secara intuitif, ini terasa seperti paket yang "lebih ramping".
Jadi, apa perbedaan yang tepat bagi konsumen perpustakaan saya? Jika seseorang mencoba menggunakannya dalam aplikasi UWP, apakah bentuk dependensi kedua yang "dipangkas" berarti aplikasi yang dihasilkan akan lebih kecil?
Dengan tidak mendokumentasikan DisableImplicitFrameworkReferences
secara jelas (sejauh yang saya lihat; saya membacanya dalam sebuah masalah ) dan dengan menjadikan ketergantungan implisit sebagai default saat membuat proyek, Microsoft mendorong pengguna untuk hanya bergantung pada metapackage - tetapi bagaimana saya bisa yakin itu tidak memiliki kerugian saat saya memproduksi paket perpustakaan kelas?
sumber
Hello World!
aplikasi mandiri dikurangi menjadi <10MB.Jawaban:
Di masa lalu, kami telah memberikan rekomendasi kepada pengembang untuk tidak mereferensikan paket meta (
NETStandard.Library
) dari paket NuGet tetapi mereferensikan paket individual, sepertiSystem.Runtime
danSystem.Collections
. Alasannya adalah bahwa kami menganggap paket meta sebagai singkatan dari sekumpulan paket yang merupakan blok penyusun atom sebenarnya dari platform .NET. Asumsinya adalah: kita mungkin akan membuat platform .NET lain yang hanya mendukung beberapa blok atom ini tetapi tidak semuanya. Karenanya, semakin sedikit paket yang Anda rujuk, semakin portabel Anda. Ada juga kekhawatiran tentang bagaimana perkakas kami menangani grafik paket besar.Ke depannya, kami akan menyederhanakan ini:
.NET Standard adalah blok bangunan atom . Dengan kata lain, platform baru tidak diizinkan untuk membuat subset .NET Standard - mereka harus menerapkan semuanya.
Kami beralih dari menggunakan paket untuk mendeskripsikan platform kami , termasuk .NET Standard.
Artinya, Anda tidak perlu lagi merujuk paket NuGet apa pun untuk .NET Standard. Anda menyatakan ketergantungan Anda dengan folder lib, yang persis seperti cara kerjanya untuk semua platform .NET lainnya, khususnya .NET Framework.
Namun, saat ini perkakas kami masih akan terbakar dalam referensi ke
NETStandard.Library
. Tidak ada salahnya juga, itu hanya akan menjadi mubazir untuk bergerak maju.Saya akan memperbarui FAQ di repo Standar .NET untuk menyertakan pertanyaan ini.
Pembaruan : Pertanyaan ini sekarang menjadi bagian dari FAQ .
sumber
Tim biasanya merekomendasikan untuk mencari tahu apa set paket tertipis itu. Mereka tidak lagi melakukan ini, dan merekomendasikan orang-orang hanya membawa NETStandard.Library sebagai gantinya (dalam kasus proyek bergaya SDK, ini akan dilakukan secara otomatis untuk Anda).
Saya tidak pernah mendapatkan jawaban yang benar-benar terus terang tentang mengapa itu terjadi, jadi izinkan saya untuk membuat beberapa tebakan.
Alasan utamanya mungkin karena hal itu memungkinkan mereka menyembunyikan perbedaan versi pustaka dependen yang seharusnya Anda lacak sendiri saat mengubah kerangka kerja target. Ini juga merupakan sistem yang jauh lebih ramah pengguna dengan file proyek berbasis SDK, karena Anda terus terang tidak memerlukan referensi apa pun untuk mendapatkan bagian yang layak dari platform (seperti yang biasa Anda lakukan dengan referensi default di Desktop-land, terutama mscorlib ).
Dengan mendorong meta-definisi tentang apa artinya menjadi
netstandard
pustaka, ataunetcoreapp
aplikasi ke dalam paket NuGet yang sesuai, mereka tidak perlu membangun pengetahuan khusus apa pun ke dalam definisi hal-hal itu seperti yang dilihat oleh Visual Studio (ataudotnet new
).Analisis statis dapat digunakan selama publikasi untuk membatasi DLL yang dikirim, yang merupakan sesuatu yang mereka lakukan saat ini saat melakukan kompilasi asli untuk UWP (meskipun dengan beberapa peringatan). Mereka tidak melakukannya hari ini untuk .NET Core, tetapi saya menganggap ini adalah pengoptimalan yang telah mereka pertimbangkan (serta mendukung kode asli).
Tidak ada yang menghentikan Anda untuk menjadi sangat selektif, jika Anda memilihnya. Saya yakin Anda akan menemukan bahwa Anda hampir menjadi satu-satunya yang melakukannya, yang juga mengalahkan tujuan (karena akan diasumsikan semua orang membawa
NETStandard.Library
atauMicrosoft.NETCore.App
).sumber
NETStandard.Library
. Ini agak terpenuhi dengan sendirinya, tentu saja ... jika saya bergantung padaNETStandard.Library
Waktu Noda, itu berarti perpustakaan lain yang dibangun di atas Waktu Noda tidak memiliki alasan untuk memangkas ketergantungan, dll. Sangat menggoda untuk selektif untuk saat ini (Waktu Noda adalah menuju 2.0) kemudian bersantai sedikit kemudian setelah konvensi telah ditetapkan - mengubah dari selektif ke berbasis lib akan menjadi perubahan yang tidak melanggar, saya berasumsi, tetapi sebaliknya tidak benar.Anda tidak perlu menonaktifkan referensi implisit. Semua platform tempat library dapat dijalankan sudah memiliki rakitan yang diperlukan
NETStandard.Library
dependensi.Pustaka Standar .NET adalah spesifikasi, kumpulan rakitan referensi yang Anda kompilasi yang menyediakan sekumpulan API yang dijamin ada di kumpulan platform dan versi platform yang diketahui, seperti .NET Core atau .NET Framework . Ini bukan implementasi dari rakitan ini, hanya bentuk API yang cukup untuk memungkinkan compiler berhasil membuat kode Anda.
Implementasi untuk API ini disediakan oleh platform target, seperti .NET Core, Mono, atau .NET Framework. Mereka dikirimkan dengan platform, karena mereka adalah bagian penting dari platform. Jadi tidak perlu menentukan set dependensi yang lebih kecil - semuanya sudah ada, Anda tidak akan mengubahnya.
The
NETStandard.Library
paket menyediakan majelis referensi tersebut. Satu hal yang membingungkan adalah nomor versi - paketnya adalah versi 1.6.1, tetapi ini tidak berarti ".NET Standard 1.6". Ini hanya versi paketnya.Versi .NET Standard yang Anda targetkan berasal dari kerangka kerja target yang Anda tentukan dalam proyek Anda.
Jika Anda membuat pustaka dan ingin menjalankannya di .NET Standard 1.3, Anda akan mereferensikan
NETStandard.Library
paketnya, saat ini di versi 1.6.1. Tetapi yang lebih penting, file proyek Anda akan ditargetkannetstandard1.3
.The
NETStandard.Library
paket akan memberikan Anda satu set yang berbeda dari majelis referensi tergantung pada target kerangka moniker Anda (saya menyederhanakan untuk singkatnya, tetapi berpikirlib\netstandard1.0
,lib\netstandard1.1
dan kelompok ketergantungan ). Jadi jika proyek Anda menargetkannetstandard1.3
, Anda akan mendapatkan rakitan referensi 1,3. Jika Anda menargetkannetstandard1.6
, Anda akan mendapatkan rakitan referensi 1.6.Jika Anda membuat aplikasi, Anda tidak dapat menargetkan .NET Standard. Ini tidak masuk akal - Anda tidak dapat menjalankan spesifikasi. Sebaliknya, Anda menargetkan platform beton, seperti
net452
ataunetcoreapp1.1
. NuGet mengetahui pemetaan antara platform ini dannetstandard
moniker kerangka target, jadi ketahuilib\netstandardX.X
folder mana yang kompatibel dengan platform target Anda. Ia juga tahu bahwa dependensiNETStandard.Library
dipenuhi oleh platform target, jadi tidak akan menarik rakitan lain.Demikian pula, saat membuat aplikasi .NET Core mandiri, rakitan implementasi .NET Standard disalin dengan aplikasi Anda. Referensi ke
NETStandard.Library
tidak membawa aplikasi baru lainnya.Satu-satunya tempat yang dapat saya bayangkan di mana mungkin membantu untuk menghapus
NETStandard.Library
referensi adalah jika Anda menargetkan platform yang tidak mendukung .NET Standard, dan Anda dapat menemukan paket dari .NET Standard di mana semua dependensi transitif dapat berjalan di platform target Anda. Saya menduga tidak banyak paket yang sesuai dengan tagihan itu.sumber
dotnet publish
pada runtime tertentu, itu akan membawa semua dependensi, termasuk dotnet.exe (atau yang setara dengan Linux / OS X). Itu harus menjadi penerapan yang sepenuhnya berdiri sendiri pada saat itu. Lihat hasil untuk proyek uji unit: gist.github.com/bradwilson/6cc5a8fdfa18230aa6c99b851fb85c01