SDK proyek .NET

Proyek .NET modern dikaitkan dengan kit pengembangan perangkat lunak (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 berikut tersedia:

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.BlazorWebAssembly The .NET Blazor WebAssembly SDK https://github.com/dotnet/aspnetcore
Microsoft.NET.Sdk.Razor .NET Razor SDK https://github.com/dotnet/aspnetcore
Microsoft.NET.Sdk.Worker .NET Worker Service SDK

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

Anda juga dapat menulis SDK Anda sendiri yang dapat didistribusikan melalui NuGet.

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.

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">
  ...
</Project>

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

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 PreBuild dan PostBuild menargetkan, jadi dengan menggunakan nama tersebut, Anda dapat mengedit perintah di IDE.
  • Properti PreBuildEvent dan PostBuildEvent 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.

Lihat juga