SDK proyek .NET
Proyek .NET modern dikaitkan dengan kit pengembangan perangkat lunak proyek (SDK). Setiap proyek SDK adalah sekumpulan target MSBuild dan tugas terkait yang bertanggung jawab untuk mengkompilasi, mengemas, dan menerbitkan kode. Proyek yang mereferensikan proyek SDK terkadang disebut sebagai proyek bergaya SDK.
SDK yang Tersedia
SDK yang tersedia meliputi:
ID | Deskripsi | Repo |
---|---|---|
Microsoft.NET.Sdk |
SDK .NET | https://github.com/dotnet/sdk |
Microsoft.NET.Sdk.Web |
.NET Web SDK | https://github.com/dotnet/sdk |
Microsoft.NET.Sdk.Razor |
.NET Razor SDK | https://github.com/dotnet/aspnetcore |
Microsoft.NET.Sdk.BlazorWebAssembly |
The .NET Blazor WebAssembly SDK | https://github.com/dotnet/aspnetcore |
Microsoft.NET.Sdk.Worker |
.NET Worker Service SDK | https://github.com/dotnet/aspnetcore |
Aspire.AppHost.Sdk |
.NET Aspire SDK | https://github.com/dotnet/aspire |
MSTest.Sdk |
MSTest SDK | https://github.com/microsoft/testfx |
.NET SDK adalah SDK dasar untuk .NET. SDK lainnya mereferensikan .NET SDK, dan proyek yang terkait dengan SDK lainnya memiliki semua properti .NET SDK yang tersedia untuk mereka. Web SDK, misalnya, bergantung pada .NET SDK dan Razor SDK.
Untuk proyek Formulir Windows dan Windows Presentation Foundation (WPF), Anda menentukan .NET SDK (Microsoft.NET.Sdk
) dan mengatur beberapa properti tambahan dalam file proyek. Untuk informasi selengkapnya, lihat Mengaktifkan .NET Desktop SDK.
MSBuild SDK, yang dapat Anda gunakan untuk mengonfigurasi dan memperluas build Anda, tercantum di MSBuild SDK.
Anda juga dapat menulis SDK Anda sendiri yang dapat didistribusikan melalui NuGet.
File proyek
Proyek .NET didasarkan pada format MSBuild . File proyek, yang memiliki ekstensi seperti .csproj untuk proyek C# dan .fsproj untuk proyek F#, dalam format XML. Elemen akar dari file proyek MSBuild adalah elemen Project . Elemen Project
ini memiliki atribut opsional Sdk
yang menentukan SDK (dan versi) mana yang akan digunakan. Untuk menggunakan alat .NET dan membangun kode Anda, atur Sdk
atribut ke salah satu ID dalam tabel SDK yang Tersedia.
<Project Sdk="Microsoft.NET.Sdk">
<!-- Omitted for brevity... -->
</Project>
Atribut Project/Sdk
dan Sdk
elemen mengaktifkan SDK aditif. Pertimbangkan contoh berikut, di mana .NET Aspire SDK (Aspire.AppHost.Sdk
) ditambahkan ke proyek di Microsoft.NET.Sdk
atas :
<Project Sdk="Microsoft.NET.Sdk">
<Sdk Name="Aspire.AppHost.Sdk" Version="9.0.0" />
<!-- Omitted for brevity... -->
</Project>
Dalam file proyek sebelumnya, kedua SDK digunakan untuk menyelesaikan dependensi secara aditif. Untuk informasi selengkapnya, lihat .NET Aspire SDK.
Untuk menentukan SDK yang berasal dari NuGet, sertakan versi di akhir nama, atau tentukan nama dan versi dalam file global.json .
<Project Sdk="MSBuild.Sdk.Extras/2.0.54">
...
</Project>
Cara lain untuk menentukan SDK adalah dengan elemen tingkat Sdk
atas:
<Project>
<Sdk Name="Microsoft.NET.Sdk" />
...
</Project>
Mereferensikan SDK dengan salah satu cara ini sangat menyederhanakan file proyek untuk .NET. Saat mengevaluasi proyek, MSBuild menambahkan impor implisit untuk Sdk.props
di bagian atas file proyek dan Sdk.targets
di bagian bawah.
<Project>
<!-- Implicit top import -->
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
...
<!-- Implicit bottom import -->
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
</Project>
Tip
Pada komputer Windows, file Sdk.props dan Sdk.targets dapat ditemukan di folder %ProgramFiles%\dotnet\sdk\[version]\Sdks\Microsoft.NET.Sdk\Sdk .
Prapemroscesan file proyek
Anda dapat melihat proyek yang diperluas sepenuhnya saat MSBuild melihatnya setelah SDK dan targetnya disertakan dengan menggunakan dotnet msbuild -preprocess
perintah . Sakelar dotnet msbuild
perintah menunjukkan file mana yang diimpor, sumbernya, dan kontribusinya ke build tanpa benar-benar membangun proyek.
Jika proyek memiliki beberapa kerangka kerja target, fokuskan hasil perintah hanya pada satu kerangka kerja dengan menentukannya sebagai properti MSBuild. Contohnya:
dotnet msbuild -property:TargetFramework=net8.0 -preprocess:output.xml
Default mencakup dan mengecualikan
Default mencakup dan mengecualikan itemCompile
, sumber daya yang disematkan, dan None
item ditentukan dalam SDK. Tidak seperti proyek .NET Framework non-SDK, Anda tidak perlu menentukan item ini dalam file proyek Anda, karena default mencakup kasus penggunaan yang paling umum. Perilaku ini membuat file proyek lebih kecil dan lebih mudah dipahami dan diedit dengan tangan, jika diperlukan.
Tabel berikut menunjukkan elemen mana dan glob mana yang disertakan dan dikecualikan dalam .NET SDK:
Elemen | Sertakan glob | Mengecualikan glob | Menghapus glob |
---|---|---|---|
Compile | **/*.cs (atau ekstensi bahasa lainnya) | **/*.pengguna; **/*.*proj; **/*.sln; **/*.vssscc | T/A |
EmbeddedResource | **/*.resx | **/*.pengguna; **/*.*proj; **/*.sln; **/*.vssscc | T/A |
None | **/* | **/*.pengguna; **/*.*proj; **/*.sln; **/*.vssscc | **/*.Cs; **/*.resx |
Catatan
Folder ./bin
dan ./obj
, yang diwakili oleh $(BaseOutputPath)
properti dan $(BaseIntermediateOutputPath)
MSBuild, dikecualikan dari glob secara default. Pengecualian diwakili oleh properti DefaultItemExcludes.
.NET Desktop SDK memiliki tambahan termasuk dan mengecualikan untuk WPF. Untuk informasi selengkapnya, lihat Default WPF menyertakan dan mengecualikan.
Jika Anda secara eksplisit menentukan salah satu item ini dalam file proyek, Kemungkinan Anda akan mendapatkan kesalahan build NETSDK1022 . Untuk informasi tentang cara mengatasi kesalahan, lihat NETSDK1022: Item duplikat disertakan.
Implisit menggunakan direktif
Mulai dari .NET 6, arahan implisit global using
ditambahkan ke proyek C# baru. Ini berarti Anda dapat menggunakan jenis yang ditentukan dalam namespace layanan ini tanpa harus menentukan nama yang sepenuhnya memenuhi syarat atau menambahkan using
arahan secara manual. Aspek implisit mengacu pada fakta bahwa global using
arahan ditambahkan ke file yang dihasilkan dalam direktori obj proyek.
Arahan implisit global using
ditambahkan untuk proyek yang menggunakan salah satu SDK berikut:
Microsoft.NET.Sdk
Microsoft.NET.Sdk.Web
Microsoft.NET.Sdk.Worker
Microsoft.NET.Sdk.WindowsDesktop
global using
Direktif ditambahkan untuk setiap namespace dalam sekumpulan namespace default yang didasarkan pada SDK proyek. Namespace default ini diperlihatkan dalam tabel berikut.
SDK | Namespace default |
---|---|
Microsoft.NET.Sdk | System System.Collections.Generic System.IO System.Linq System.Net.Http System.Threading System.Threading.Tasks |
Microsoft.NET.Sdk.Web | Namespace Microsoft.NET.Sdk System.Net.Http.Json Microsoft.AspNetCore.Builder Microsoft.AspNetCore.Hosting Microsoft.AspNetCore.Http Microsoft.AspNetCore.Routing Microsoft.Extensions.Configuration Microsoft.Extensions.DependencyInjection Microsoft.Extensions.Hosting Microsoft.Extensions.Logging |
Microsoft.NET.Sdk.Worker | Namespace Microsoft.NET.Sdk Microsoft.Extensions.Configuration Microsoft.Extensions.DependencyInjection Microsoft.Extensions.Hosting Microsoft.Extensions.Logging |
Microsoft.NET.Sdk.WindowsDesktop (Formulir Windows) | Namespace Microsoft.NET.Sdk System.Drawing System.Windows.Forms |
Microsoft.NET.Sdk.WindowsDesktop (WPF) | Namespace Microsoft.NET.Sdk Dihapus System.IO Dihapus System.Net.Http |
Jika Anda ingin menonaktifkan fitur ini, atau jika Anda ingin mengaktifkan arahan implisit global using
dalam proyek C# yang ada, Anda dapat melakukannya melalui ImplicitUsings
properti MSBuild.
Anda dapat menentukan arahan implisit global using
tambahan dengan menambahkan Using
item (atau Import
item untuk proyek Visual Basic) ke file proyek Anda, misalnya:
<ItemGroup>
<Using Include="System.IO.Pipes" />
</ItemGroup>
Catatan
Dimulai dengan .NET 8 SDK, System.Net.Httptidak lagi disertakan saat Microsoft.NET.Sdk
menargetkan .NET Framework.
Referensi paket implisit
Saat proyek Anda menargetkan .NET Standard 1.0-2.0, .NET SDK menambahkan referensi implisit ke metapackage tertentu. Metapackage adalah paket berbasis kerangka kerja yang hanya terdiri dari dependensi pada paket lain. Metapackages secara implisit dirujuk berdasarkan kerangka kerja target yang ditentukan dalam properti TargetFramework atau TargetFrameworks (plural) dari file proyek Anda.
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net462</TargetFrameworks>
</PropertyGroup>
Jika diperlukan, Anda dapat menonaktifkan referensi paket implisit menggunakan properti DisableImplicitFrameworkReferences , dan menambahkan referensi eksplisit hanya ke kerangka kerja atau paket yang Anda butuhkan.
Rekomendasi:
- Saat menargetkan .NET Framework atau .NET Standard 1.0-2.0, jangan tambahkan referensi eksplisit ke
NETStandard.Library
metapackages melalui<PackageReference>
item dalam file proyek Anda. Untuk proyek .NET Standard 1.0-2.0, metapackage ini dirujuk secara implisit. Untuk proyek .NET Framework, jika ada versiNETStandard.Library
yang diperlukan saat menggunakan paket NuGet berbasis Standar .NET, NuGet secara otomatis menginstal versi tersebut. - Jika Anda memerlukan versi tertentu dari
NETStandard.Library
metapackage saat menargetkan .NET Standard 1.0-2.0, Anda dapat menggunakan<NetStandardImplicitPackageVersion>
properti dan mengatur versi yang Anda butuhkan.
Membangun peristiwa
Dalam proyek bergaya SDK, gunakan target MSBuild bernama PreBuild
atau PostBuild
dan atur BeforeTargets
properti untuk PreBuild
atau AfterTargets
properti untuk PostBuild
.
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Exec Command=""$(ProjectDir)PreBuildEvent.bat" "$(ProjectDir)..\" "$(ProjectDir)" "$(TargetDir)"" />
</Target>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="echo Output written to $(TargetDir)" />
</Target>
Catatan
- Anda dapat menggunakan nama apa pun untuk target MSBuild. Namun, IDE Visual Studio mengenali
PreBuild
danPostBuild
menargetkan, jadi dengan menggunakan nama tersebut, Anda dapat mengedit perintah di IDE. - Properti
PreBuildEvent
danPostBuildEvent
tidak direkomendasikan dalam proyek gaya SDK, karena makro seperti$(ProjectDir)
tidak diselesaikan. Misalnya, kode berikut tidak didukung:
<PropertyGroup>
<PreBuildEvent>"$(ProjectDir)PreBuildEvent.bat" "$(ProjectDir)..\" "$(ProjectDir)" "$(TargetDir)"</PreBuildEvent>
</PropertyGroup>
Mengkustomisasi build
Ada berbagai cara untuk menyesuaikan build. Anda mungkin ingin mengambil alih properti dengan meneruskannya sebagai argumen ke perintah msbuild atau dotnet . Anda juga dapat menambahkan properti ke file proyek atau ke file Directory.Build.props. Untuk daftar properti yang berguna untuk proyek .NET, lihat Referensi MSBuild untuk proyek .NET SDK.
Tip
Cara mudah untuk membuat file Directory.Build.props baru dari baris perintah adalah dengan menggunakan perintah dotnet new buildprops
di akar repositori Anda.
Target kustom
Proyek .NET dapat mengemas target dan properti MSBuild kustom untuk digunakan oleh proyek yang menggunakan paket. Gunakan jenis ekstensibilitas ini saat Anda ingin:
- Perluas proses build.
- Akses artefak proses build, seperti file yang dihasilkan.
- Periksa konfigurasi tempat build dipanggil.
Anda menambahkan target atau properti build kustom dengan menempatkan file dalam formulir <package_id>.targets
atau <package_id>.props
(misalnya, Contoso.Utility.UsefulStuff.targets
) di folder build proyek.
XML berikut adalah cuplikan dari file .csproj yang menginstruksikan perintah apa yang harus dimasuki dotnet pack
. Elemen menempatkan <ItemGroup Label="dotnet pack instructions">
file target ke dalam folder build di dalam paket. Elemen menempatkan <Target Name="CollectRuntimeOutputs" BeforeTargets="_GetPackageFiles">
rakitan dan .json file ke dalam folder build .
<Project Sdk="Microsoft.NET.Sdk">
...
<ItemGroup Label="dotnet pack instructions">
<Content Include="build\*.targets">
<Pack>true</Pack>
<PackagePath>build\</PackagePath>
</Content>
</ItemGroup>
<Target Name="CollectRuntimeOutputs" BeforeTargets="_GetPackageFiles">
<!-- Collect these items inside a target that runs after build but before packaging. -->
<ItemGroup>
<Content Include="$(OutputPath)\*.dll;$(OutputPath)\*.json">
<Pack>true</Pack>
<PackagePath>build\</PackagePath>
</Content>
</ItemGroup>
</Target>
...
</Project>
Untuk menggunakan target kustom dalam proyek Anda, tambahkan PackageReference
elemen yang menunjuk ke paket dan versinya. Tidak seperti alat, paket target kustom disertakan dalam penutupan dependensi proyek yang mengonsumsi.
Anda dapat mengonfigurasi cara menggunakan target kustom. Karena ini adalah target MSBuild, target dapat bergantung pada target tertentu, dijalankan setelah target lain, atau dipanggil secara manual dengan menggunakan dotnet msbuild -t:<target-name>
perintah . Namun, untuk memberikan pengalaman pengguna yang lebih baik, Anda dapat menggabungkan alat per proyek dan target kustom. Dalam skenario ini, alat per proyek menerima parameter apa pun yang diperlukan dan menerjemahkannya ke dalam pemanggilan yang diperlukan dotnet msbuild
yang menjalankan target. Anda dapat melihat sampel sinergi semacam ini pada repositori sampel MVP Summit 2016 Hackathon dalam dotnet-packer
proyek.