Zestawy SDK projektu .NET

Nowoczesne projekty platformy .NET są skojarzone z zestawem SDK (Software Development Kit). Każdy zestaw SDK projektu to zestaw obiektów docelowych programu MSBuild i skojarzone zadania, które są odpowiedzialne za kompilowanie, pakowanie i publikowanie kodu. Projekt, który odwołuje się do zestawu SDK projektu, jest czasami nazywany projektem w stylu zestawu SDK.

Dostępne zestawy SDK

Dostępne są następujące zestawy SDK:

ID opis Repozytorium
Microsoft.NET.Sdk Zestaw SDK platformy .NET https://github.com/dotnet/sdk
Microsoft.NET.Sdk.Web Zestaw .NET Web SDK https://github.com/dotnet/sdk
Microsoft.NET.Sdk.BlazorWebAssembly Zestaw .NET Blazor WebAssembly SDK https://github.com/dotnet/aspnetcore
Microsoft.NET.Sdk.Razor Zestaw .NET Razor SDK https://github.com/dotnet/aspnetcore
Microsoft.NET.Sdk.Worker Zestaw SDK usługi procesu roboczego platformy .NET

Zestaw .NET SDK jest podstawowym zestawem SDK dla platformy .NET. Inne zestawy SDK odwołują się do zestawu .NET SDK i projektów skojarzonych z innymi zestawami SDK mają dostępne wszystkie właściwości zestawu SDK platformy .NET. Zestaw SDK sieci Web zależy na przykład zarówno od zestawu SDK platformy .NET, jak i zestawu SDK Razor.

Możesz również utworzyć własny zestaw SDK, który można dystrybuować za pośrednictwem narzędzia NuGet.

W przypadku projektów Windows Forms i Windows Presentation Foundation (WPF) należy określić zestaw .NET SDK (Microsoft.NET.Sdk) i ustawić kilka dodatkowych właściwości w pliku projektu. Aby uzyskać więcej informacji, zobacz Włączanie zestawu .NET Desktop SDK.

Pliki projektu

Projekty .NET są oparte na formacie MSBuild . Pliki projektu, które mają rozszerzenia, takie jak csproj dla projektów C# i .fsproj dla projektów F#, są w formacie XML. Elementem głównym pliku projektu MSBuild jest element Project . Element Project ma opcjonalny Sdk atrybut określający, który zestaw SDK (i wersja) ma być używany. Aby użyć narzędzi platformy .NET i skompilować kod, ustaw Sdk atrybut na jeden z identyfikatorów w tabeli Dostępne zestawy SDK .

<Project Sdk="Microsoft.NET.Sdk">
  ...
</Project>

Aby określić zestaw SDK pochodzący z pakietu NuGet, dołącz wersję na końcu nazwy lub określ nazwę i wersję w pliku global.json .

<Project Sdk="MSBuild.Sdk.Extras/2.0.54">
  ...
</Project>

Innym sposobem określenia zestawu SDK jest element najwyższego poziomu Sdk :

<Project>
  <Sdk Name="Microsoft.NET.Sdk" />
  ...
</Project>

Odwoływanie się do zestawu SDK w jeden z tych sposobów znacznie upraszcza pliki projektu dla platformy .NET. Podczas oceniania projektu program MSBuild dodaje niejawne importy w Sdk.props górnej części pliku projektu i Sdk.targets u dołu.

<Project>
  <!-- Implicit top import -->
  <Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
  ...
  <!-- Implicit bottom import -->
  <Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
</Project>

Napiwek

Na maszynie z systemem Windows pliki Sdk.props i Sdk.targets można znaleźć w folderze %ProgramFiles%\dotnet\sdk\[version]\Sdks\Microsoft.NET.Sdk\Sdk .

Wstępne przetwarzanie pliku projektu

Możesz zobaczyć w pełni rozwinięty projekt, ponieważ program MSBuild widzi go po dołączeniu zestawu SDK i jego elementów docelowych za pomocą dotnet msbuild -preprocess polecenia . Przełącznik przetwarzaniadotnet msbuild wstępnego polecenia pokazuje, które pliki są importowane, ich źródła i współtworzenie kompilacji bez faktycznego kompilowania projektu.

Jeśli projekt ma wiele platform docelowych, skoncentruj wyniki polecenia tylko na jednej strukturze, określając ją jako właściwość MSBuild. Na przykład:

dotnet msbuild -property:TargetFramework=net8.0 -preprocess:output.xml

Domyślne dołączanie i wykluczanie

Wartości domyślne obejmują i wykluczają elementy, zasoby osadzone iNoneelementy są zdefiniowane w zestawie SDK.Compile W przeciwieństwie do projektów programu .NET Framework innych niż SDK nie trzeba określać tych elementów w pliku projektu, ponieważ wartości domyślne obejmują najczęściej używane przypadki użycia. To zachowanie sprawia, że plik projektu jest mniejszy i łatwiejszy do zrozumienia i edycji ręcznie, w razie potrzeby.

W poniższej tabeli pokazano, które elementy i które globy są uwzględnione i wykluczone w zestawie SDK platformy .NET:

Element Uwzględnij glob Wyklucz glob Usuń glob
Compile **/*.cs (lub inne rozszerzenia językowe) **/*.Użytkownika; **/*.*Proj; **/*.Sln; **/*.Vssscc Nie dotyczy
EmbeddedResource **/*.Resx **/*.Użytkownika; **/*.*Proj; **/*.Sln; **/*.Vssscc Nie dotyczy
None **/* **/*.Użytkownika; **/*.*Proj; **/*.Sln; **/*.Vssscc **/*.Cs; **/*.Resx

Uwaga

Foldery ./bin i, które są reprezentowane przez $(BaseOutputPath) właściwości i $(BaseIntermediateOutputPath)./obj MSBuild, są domyślnie wykluczone z elementów globs. Wykluczenia są reprezentowane przez właściwość DefaultItemExcludes.

Zestaw .NET Desktop SDK zawiera dodatkowe elementy dołączane i wykluczane dla platformy WPF. Aby uzyskać więcej informacji, zobacz WPF default includes and excludes (Domyślne dołączanie i wykluczanie WPF).

Jeśli jawnie zdefiniujesz dowolny z tych elementów w pliku projektu, prawdopodobnie wystąpi błąd kompilacji NETSDK1022. Aby uzyskać informacje na temat sposobu rozwiązywania błędu, zobacz NETSDK1022: Uwzględnione zostały zduplikowane elementy.

Niejawne dyrektywy using

Począwszy od platformy .NET 6, dyrektywy niejawne global using są dodawane do nowych projektów języka C#. Oznacza to, że można użyć typów zdefiniowanych w tych przestrzeniach nazw bez konieczności określenia ich w pełni kwalifikowanej nazwy lub ręcznego dodania using dyrektywy. Niejawny aspekt odnosi się do faktu, że global using dyrektywy są dodawane do wygenerowanego pliku w katalogu obj projektu.

Dyrektywy niejawne global using są dodawane dla projektów, które używają jednego z następujących zestawów SDK:

  • Microsoft.NET.Sdk
  • Microsoft.NET.Sdk.Web
  • Microsoft.NET.Sdk.Worker
  • Microsoft.NET.Sdk.WindowsDesktop

global using Dyrektywa jest dodawana dla każdej przestrzeni nazw w zestawie domyślnych przestrzeni nazw opartych na zestawie SDK projektu. Te domyślne przestrzenie nazw są wyświetlane w poniższej tabeli.

SDK Domyślne przestrzenie nazw
Microsoft.NET.Sdk System
System.Collections.Generic
System.IO
System.Linq
System.Net.Http
System.Threading
System.Threading.Tasks
Microsoft.NET.Sdk.Web Przestrzenie nazw 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 Przestrzenie nazw Microsoft.NET.Sdk
Microsoft.Extensions.Configuration
Microsoft.Extensions.DependencyInjection
Microsoft.Extensions.Hosting
Microsoft.Extensions.Logging
Microsoft.NET.Sdk.WindowsDesktop (Windows Forms) Przestrzenie nazw Microsoft.NET.Sdk
System.Drawing
System.Windows.Forms
Microsoft.NET.Sdk.WindowsDesktop (WPF) Przestrzenie nazw Microsoft.NET.Sdk
Usunięte System.IO
Usunięte System.Net.Http

Jeśli chcesz wyłączyć tę funkcję lub chcesz włączyć niejawne global using dyrektywy w istniejącym projekcie języka C#, możesz to zrobić za pośrednictwem ImplicitUsings właściwości MSBuild.

Możesz określić dodatkowe niejawne global using dyrektywy, dodając Using elementy (lub Import elementy dla projektów Visual Basic) do pliku projektu, na przykład:

<ItemGroup>
  <Using Include="System.IO.Pipes" />
</ItemGroup>

Niejawne odwołania do pakietów

Gdy projekt jest przeznaczony dla platformy .NET Standard 1.0–2.0, zestaw .NET SDK dodaje niejawne odwołania do niektórych metapakietów. Metapakiet to pakiet oparty na strukturze, który składa się tylko z zależności od innych pakietów. Metapakiety są niejawnie przywołyzane na podstawie platform docelowych określonych we właściwości TargetFramework lub TargetFrameworks (mnogiej) pliku projektu.

<PropertyGroup>
  <TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
  <TargetFrameworks>netstandard2.0;net462</TargetFrameworks>
</PropertyGroup>

W razie potrzeby można wyłączyć odwołania do niejawnego pakietu przy użyciu właściwości DisableImplicitFrameworkReferences i dodać jawne odwołania tylko do potrzebnych struktur lub pakietów.

Rekomendacje:

  • W przypadku określania wartości docelowych dla programu .NET Framework lub .NET Standard 1.0-2.0 nie należy dodawać jawnego odwołania do NETStandard.Library metapakietów za pośrednictwem <PackageReference> elementu w pliku projektu. W przypadku projektów .NET Standard 1.0-2.0 te metapakiet są niejawnie przywołyzane. W przypadku projektów .NET Framework, jeśli w przypadku korzystania z pakietu NuGet opartego na platformie .NET Standard wymagana jest dowolna wersja NETStandard.Library , program NuGet automatycznie instaluje ją.
  • Jeśli potrzebujesz określonej wersji NETStandard.Library metapakiety podczas określania wartości docelowej .NET Standard 1.0-2.0, możesz użyć <NetStandardImplicitPackageVersion> właściwości i ustawić potrzebną wersję.

Zdarzenia kompilacji

W projektach w stylu zestawu SDK należy użyć obiektu docelowego MSBuild o nazwie PreBuild lub ustawić BeforeTargets właściwość dla PreBuild lub AfterTargets dla właściwości PostBuildPostBuild .

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

Uwaga

  • Możesz użyć dowolnej nazwy dla obiektów docelowych MSBuild. Jednak środowisko IDE programu Visual Studio rozpoznaje PreBuild i PostBuild obiekty docelowe, więc używając tych nazw, można edytować polecenia w środowisku IDE.
  • Właściwości PreBuildEvent i PostBuildEvent nie są zalecane w projektach w stylu zestawu SDK, ponieważ makra, takie jak $(ProjectDir) nie są rozwiązywane. Na przykład następujący kod nie jest obsługiwany:
<PropertyGroup>
  <PreBuildEvent>"$(ProjectDir)PreBuildEvent.bat" "$(ProjectDir)..\" "$(ProjectDir)" "$(TargetDir)"</PreBuildEvent>
</PropertyGroup>

Dostosowywanie kompilacji

Istnieją różne sposoby dostosowywania kompilacji. Możesz przesłonić właściwość, przekazując ją jako argument do polecenia msbuild lub dotnet . Możesz również dodać właściwość do pliku projektu lub do pliku Directory.Build.props. Aby uzyskać listę przydatnych właściwości projektów platformy .NET, zobacz Dokumentacja programu MSBuild dla projektów zestawu .NET SDK.

Napiwek

Łatwym sposobem utworzenia nowego pliku Directory.Build.props z wiersza polecenia jest użycie polecenia dotnet new buildprops w katalogu głównym repozytorium.

Niestandardowe obiekty docelowe

Projekty platformy .NET mogą pakować niestandardowe obiekty docelowe i właściwości programu MSBuild do użycia przez projekty korzystające z pakietu. Użyj tego typu rozszerzalności, jeśli chcesz:

  • Rozszerz proces kompilacji.
  • Uzyskaj dostęp do artefaktów procesu kompilacji, takich jak wygenerowane pliki.
  • Sprawdź konfigurację, w której jest wywoływana kompilacja.

Niestandardowe obiekty docelowe kompilacji lub właściwości można dodać, umieszczając pliki w formularzu <package_id>.targets lub <package_id>.props (na przykład Contoso.Utility.UsefulStuff.targets) w folderze kompilacji projektu.

Poniższy kod XML to fragment kodu z pliku csproj , który instruuje dotnet pack polecenie, co należy spakować. Element <ItemGroup Label="dotnet pack instructions"> umieszcza pliki docelowe w folderze kompilacji wewnątrz pakietu. Element <Target Name="CollectRuntimeOutputs" BeforeTargets="_GetPackageFiles"> umieszcza zestawy i pliki .json w folderze kompilacji.

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

Aby użyć niestandardowego obiektu docelowego w projekcie, dodaj PackageReference element wskazujący pakiet i jego wersję. W przeciwieństwie do narzędzi pakiet obiektów docelowych niestandardowych jest uwzględniony w zamykaniu zależności projektu zużywających.

Możesz skonfigurować sposób używania niestandardowego obiektu docelowego. Ponieważ jest to element docelowy programu MSBuild, może on zależeć od danego obiektu docelowego, uruchomić go po innym obiekcie docelowym lub ręcznie wywołać za pomocą dotnet msbuild -t:<target-name> polecenia . Jednak aby zapewnić lepsze środowisko użytkownika, można połączyć narzędzia dla poszczególnych projektów i niestandardowe obiekty docelowe. W tym scenariuszu narzędzie dla projektu akceptuje wszystkie wymagane parametry i przekłada je na wymagane dotnet msbuild wywołanie, które wykonuje obiekt docelowy. W projekcie możesz zobaczyć próbkę tego rodzaju synergii na forum MVP Summit 2016 Hackathon samples (Repozytorium próbek maratonu programowego MVP 2016).dotnet-packer

Zobacz też