Udostępnij za pośrednictwem


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 zestawy SDK obejmują:

Identyfikator 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.Razor Pakiet .NET Razor SDK https://github.com/dotnet/aspnetcore
Microsoft.NET.Sdk.BlazorWebAssembly Pakiet .NET Blazor WebAssembly SDK https://github.com/dotnet/aspnetcore
Microsoft.NET.Sdk.Worker SDK usługi roboczej .NET https://github.com/dotnet/aspnetcore
Aspire.AppHost.Sdk Zestaw .NET Aspire SDK https://github.com/dotnet/aspire
MSTest.Sdk MSTest SDK https://github.com/microsoft/testfx

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

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.

Zestawy SDK programu MSBuild, których można użyć do konfigurowania i rozszerzania kompilacji, są wyświetlane w temacie Zestawy SDK programu MSBuild.

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

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">
    <!-- Omitted for brevity... -->
</Project>

Atrybut Project/Sdk i element Sdk umożliwiają dodatkowe zestawy SDK. Rozważmy następujący przykład, w którym zestaw .NET Aspire SDK (Aspire.AppHost.Sdk) jest dodawany do projektu na szczycie Microsoft.NET.Sdk:

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

    <Sdk Name="Aspire.AppHost.Sdk" Version="9.0.0" />
    <!-- Omitted for brevity... -->

</Project>

W poprzednim pliku projektu oba zestawy SDK są używane do rozpoznawania zależności w charakterze addytywnej. Aby uzyskać więcej informacji, zobacz .NET Aspire SDK.

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ć całkowicie rozbudowany projekt, tak jak widzi go MSBuild, po dołączeniu zestawu SDK i jego celów, za pomocą polecenia dotnet msbuild -preprocess. Przełącznik przetwarzania wstępnego w poleceniu dotnet msbuild pokazuje, które pliki są importowane, ich źródła oraz ich wkład w kompilację, 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 dotyczące dołączania i wykluczania elementów, zasobów osadzonych oraz elementów są zdefiniowane w zestawie SDK. 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:

Składnik Uwzględnij glob Wyklucz glob Usuń glob
Compile **/*.cs (lub inne rozszerzenia językowe) **/*.użytkownik; **/*.*proj; **/*.sln(x); **/*.vssscc Nie dotyczy
EmbeddedResource **/*.resx **/*.użytkownik; **/*.*proj; **/*.sln(x); **/*.vssscc Nie dotyczy
None **/* **/*.użytkownik; **/*.*proj; **/*.sln(x); **/*.vssscc **/*.Cs; **/*.resx

Uwaga

Foldery ./bin i ./obj, które są reprezentowane przez właściwości MSBuild $(BaseOutputPath) i $(BaseIntermediateOutputPath), są domyślnie wykluczone z wzorców glob. Wykluczenia są określane 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 Domyślne dołączanie i wykluczanie w 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ędniono zduplikowane elementy.

Niejawne dyrektywy 'using'

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

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

Dla każdej przestrzeni nazw w zestawie domyślnych przestrzeni nazw, które są oparte na SDK projektu, dodawana jest dyrektywa global using. Te domyślne przestrzenie nazw są wyświetlane w poniższej tabeli.

Zestaw do tworzenia oprogramowania 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>

Uwaga

Począwszy od zestawu .NET 8 SDK, System.Net.Http nie jest już uwzględniany w Microsoft.NET.Sdk przypadku określania platformy .NET Framework.

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ływane na podstawie frameworków docelowych określonych w właściwości TargetFramework lub TargetFrameworks 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 ukierunkowania na .NET Framework lub .NET Standard 1.0-2.0 nie należy dodawać jawnego odwołania do metapakietów NETStandard.Library poprzez element <PackageReference> 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 metapakietu NETStandard.Library dla .NET Standard 1.0-2.0, możesz użyć pola właściwości <NetStandardImplicitPackageVersion> i ustawić potrzebną wersję.

Zdarzenia budowania

W projektach w stylu SDK należy użyć celu MSBuild o nazwie PreBuild lub PostBuild i ustawić właściwość BeforeTargets dla PreBuild lub właściwość AfterTargets dla 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>

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 cele

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 element PackageReference, który wskazuje na pakiet i jego wersję. W przeciwieństwie do narzędzi pakiet niestandardowych celów jest uwzględniony w zależnościach projektu wykorzystującego.

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 repozytorium próbek MVP Summit 2016 Hackathon w projekcie dotnet-packer możesz zobaczyć próbkę tego rodzaju synergii.

Zobacz też