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 .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 Aspire SDK (Aspire.AppHost.Sdk) ditambahkan ke proyek di Microsoft.NET.Sdkatas :

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

Petunjuk / Saran

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 sepenuhnya diperluas seperti yang dilihat MSBuild setelah SDK dan targetnya disertakan, dengan menggunakan perintah dotnet msbuild -preprocess. Sakelar preprocess dari perintah dotnet msbuild 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

SDK secara otomatis mengelola tiga jenis item untuk proyek Anda:

  • Compile item: file kode sumber (*.cs, *.vb, dan ekstensi khusus bahasa lainnya) yang dikompilasi ke dalam rakitan Anda.
  • EmbeddedResource item: *.resx file yang disematkan ke dalam rakitan Anda.
  • None item: semua file lain yang dilacak dalam proyek, seperti file konfigurasi dan konten, yang tidak dikompilasi atau disematkan.

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.

SDK menggunakan pola glob untuk menentukan file mana yang termasuk dalam setiap jenis item:

  • Sertakan glob: Menentukan file mana yang akan ditambahkan ke jenis item.
  • Mengecualikan glob: Menentukan file mana yang akan dilewati saat menerapkan glob sertakan.
  • Hapus glob: Menentukan file mana yang akan dihapus dari item yang sudah ditambahkan oleh glob include.

Tabel berikut ini memperlihatkan pola glob default untuk setiap jenis item di .NET SDK:

Elemen Sertakan glob Kecualikan glob Menghapus glob
Compile **/*.cs (atau ekstensi bahasa lainnya) **/*.pengguna; **/*.*proj; **/*.sln(x); **/*.vssscc Tidak Berlaku
EmbeddedResource **/*.resx **/*.pengguna; **/*.*proj; **/*.sln(x); **/*.vssscc T/A
None **/* **/*.pengguna; **/*.*proj; **/*.sln(x); **/*.vssscc **/*.Cs; **/*.resx

Karena None menggunakan **/* sebagai pola penggabungan, maka juga akan mencakup file .cs dan .resx yang sudah dicakup oleh Compile dan EmbeddedResource. Hapus glob (**/*.cs; **/*.resx) mencegah file tersebut muncul di kedua jenis item secara bersamaan.

Catatan

Folder ./bin dan ./obj, yang diwakili oleh properti $(BaseOutputPath) dan $(BaseIntermediateOutputPath) MSBuild, dikecualikan dari glob secara default. Pengecualian diwakili oleh properti DefaultItemExcludes.

.NET Desktop SDK memiliki tambahan pengecualian dan penyertaan untuk WPF. Untuk informasi selengkapnya, lihat penyertaan dan pengecualian default WPF.

Peringatan

Hindari menentukan Compile, EmbeddedResource, atau None item yang menduplikasi glob default Include SDK. Menduplikasi file yang disertakan menyebabkan build menyertakan file yang sama dua kali, yang mengakibatkan kesalahan build NETSDK1022 . Kustomisasi yang menggunakan Remove atau , atau yang menambahkan item setelah Anda mengatur Update, , EnableDefaultItemsatau EnableDefaultCompileItems ke EnableDefaultEmbeddedResourceItems, falsedidukung. Untuk informasi tentang cara mengatasi kesalahan, lihat NETSDK1022: Item duplikat disertakan.

Penggunaan direktif implisit

Mulai dari .NET 6, arahan implisit global using ditambahkan ke proyek C# baru. Ini berarti Anda dapat menggunakan tipe yang didefinisikan dalam namespace ini tanpa harus menentukan nama lengkapnya atau menambahkan using arahan secara manual. Aspek bersifat 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

Direktif global using ditambahkan untuk setiap namespace dalam kumpulan namespace default yang didasarkan pada SDK proyek. Namespace default ini diperlihatkan dalam tabel berikut.

SDK Namespace Bawaan
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 versi NETStandard.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="&quot;$(ProjectDir)PreBuildEvent.bat&quot; &quot;$(ProjectDir)..\&quot; &quot;$(ProjectDir)&quot; &quot;$(TargetDir)&quot;" />
</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 target PreBuild dan PostBuild, jadi dengan menggunakan nama tersebut, Anda dapat mengedit perintah di IDE.
  • Properti PreBuildEvent dan PostBuildEvent tidak direkomendasikan dalam proyek berbasis SDK, karena makro seperti $(ProjectDir) tidak dapat dipecahkan. Misalnya, kode berikut tidak didukung:
<PropertyGroup>
  <PreBuildEvent>"$(ProjectDir)PreBuildEvent.bat" "$(ProjectDir)..\" "$(ProjectDir)" "$(TargetDir)"</PreBuildEvent>
</PropertyGroup>

Sesuaikan build

Ada berbagai cara untuk menyesuaikan konfigurasi. Anda mungkin ingin mengganti 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.

Petunjuk / Saran

Cara mudah untuk membuat file Directory.Build.props baru dari baris perintah adalah dengan menggunakan perintah dotnet new buildprops di akar repositori Anda.

Target kustomisasi

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 penyusunan.
  • Akses artefak proses build, seperti file yang dihasilkan.
  • Periksa konfigurasi di bawah mana 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 dotnet pack mengenai apa yang harus dipaketkan. Elemen <ItemGroup Label="dotnet pack instructions"> menempatkan file target ke dalam folder build di dalam paket. Elemen <Target Name="CollectRuntimeOutputs" BeforeTargets="_GetPackageFiles"> menempatkan assembly dan file .json ke 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 perangkat, paket target kustom disertakan dalam rantai dependensi proyek yang digunakan.

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.

Lihat juga