Megosztás a következőn keresztül:


.NET-projekt SDK-k

A modern .NET-projektek projektszoftver-fejlesztési készlethez (SDK) vannak társítva. Minden projekt SDK msBuild célok és kapcsolódó feladatok készlete, amelyek a kód összeállításáért, csomagolásáért és közzétételéért felelősek. A projekt SDK-ra hivatkozó projekteket néha SDK-stílusú projektnek is nevezik.

Elérhető SDK-k

Az elérhető SDK-k a következők:

ID (Azonosító) Leírás Tárház
Microsoft.NET.Sdk A .NET SDK https://github.com/dotnet/sdk
Microsoft.NET.Sdk.Web A .NET Web SDK https://github.com/dotnet/sdk
Microsoft.NET.Sdk.Razor A .NET Razor SDK https://github.com/dotnet/aspnetcore
Microsoft.NET.Sdk.BlazorWebAssembly A .NET Blazor WebAssembly SDK https://github.com/dotnet/aspnetcore
Microsoft.NET.Sdk.Worker A .NET Worker Service SDK https://github.com/dotnet/aspnetcore
Aspire.AppHost.Sdk A .NET Aspire SDK https://github.com/dotnet/aspire
MSTest.Sdk Az MSTest SDK https://github.com/microsoft/testfx

A .NET SDK a .NET alap SDK-ja. A többi SDK a .NET SDK-ra hivatkozik, a többi SDK-hoz társított projektek pedig az összes .NET SDK-tulajdonsággal rendelkeznek. A webes SDK például a .NET SDK-tól és a Razor SDK-tól is függ.

Windows Forms és Windows megjelenítési alaprendszer (WPF) projektek esetén adja meg a .NET SDK-t (Microsoft.NET.Sdk), és adjon meg néhány további tulajdonságot a projektfájlban. További információ: .NET Desktop SDK engedélyezése.

A build konfigurálásához és bővítéséhez használható MSBuild SDK-k az MSBuild SDK-kban találhatók.

Saját SDK-t is létrehozhat, amely a NuGeten keresztül terjeszthető.

Projektfájlok

A .NET-projektek az MSBuild formátumon alapulnak . A C#-projektekhez a .csproj és az F#-projektekhez készült .fsproj kiterjesztésű projektfájlok XML formátumúak. Az MSBuild projektfájl gyökéreleme a Project elem. Az Project elem rendelkezik egy választható Sdk attribútummal, amely meghatározza, hogy melyik SDK-t (és verziót) használja. A .NET-eszközök használatához és a kód létrehozásához állítsa be az Sdk attribútumot az Elérhető SDK-táblák egyik azonosítójára.

<Project Sdk="Microsoft.NET.Sdk">
    <!-- Omitted for brevity... -->
</Project>

Az Project/Sdk attribútum és Sdk az elem lehetővé teszi az additív SDK-k használatát. Vegye figyelembe a következő példát, ahol a .NET Aspire SDK (Aspire.AppHost.Sdk) hozzáadódik a projekthez a Microsoft.NET.Sdkkövetkező címen:

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

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

</Project>

Az előző projektfájlban mindkét SDK az additív jellegű függőségek feloldására szolgál. További információ: .NET Aspire SDK.

A NuGetből származó SDK megadásához adja meg a név végén található verziót, vagy adja meg a nevet és a verziót a global.json fájlban.

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

Az SDK megadásának másik módja a felső szintű Sdk elem használata:

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

Ha ilyen módon hivatkozik egy SDK-ra, az jelentősen leegyszerűsíti a .NET-hez készült projektfájlokat. A projekt kiértékelése során az MSBuild implicit importokat ad hozzá a projektfájl elejére és végére.

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

Tipp.

Windows rendszerű gépeken az Sdk.props és az Sdk.targets fájlok a %ProgramFiles%\dotnet\sdk\[version]\Sdks\Microsoft.NET.Sdk\Sdk mappában találhatók.

A projektfájl előfeldolgozása

A teljesen kibővített projektet úgy láthatja, ahogy az MSBuild érzékeli, miután az SDK és annak céljai a dotnet msbuild -preprocess parancs használatával szerepelnek. A parancs előfeldolgozási kapcsolója megmutatja, dotnet msbuild hogy mely fájlokat importálja a rendszer, milyen forrásokkal és hozzájárulásokkal járul hozzá a buildhez a projekt tényleges létrehozása nélkül.

Ha a projekt több cél-keretrendszert is tartalmaz, a parancs eredményeit csak egy keretrendszerre összpontosíthatja, ha MSBuild tulajdonságként adja meg. Példa:

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

Az alapértelmezett tartalmazza és kizárja

Az alapértelmezett Compile elemek, beágyazott erőforrások, és None elemek be- és kizárása az SDK-ban van meghatározva. A nem SDK-.NET-keretrendszer projektektől eltérően ezeket az elemeket nem kell megadnia a projektfájlban, mert az alapértelmezett értékek a leggyakoribb használati esetekre vonatkoznak. Ez a viselkedés kisebbé teszi a projektfájlt, és szükség esetén könnyebben érthetővé és szerkeszthetővé teszi a projektfájlt.

Az alábbi táblázat a .NET SDK-ban szereplő és kizárt elemeket és globokat mutatja be:

Elem Glob hozzáadása Glob kizárása Glob eltávolítása
Compile **/*.cs (vagy más nyelvi bővítmények) **/*.felhasználó; **/*.*proj; **/*.sln(x); **/*.vssscc n/a
EmbeddedResource **/*.resx **/*.felhasználó; **/*.*proj; **/*.sln(x); **/*.vssscc n/a
None **/* **/*.felhasználó; **/*.*proj; **/*.sln(x); **/*.vssscc **/*.Cs; **/*.resx

Feljegyzés

Az ./bin és ./obj mappák, amelyeket a $(BaseOutputPath) és $(BaseIntermediateOutputPath) MSBuild tulajdonságok képviselnek, alapértelmezés szerint ki vannak zárva a globok mintái közül. A kizárásokat a DefaultItemExcludes tulajdonság jelöli.

A .NET Desktop SDK-nak további tartalmai és kizárásai vannak a WPF-hez. További információ: A WPF alapértelmezett tartalma és kizárása.

Ha a projektfájlban explicit módon definiálja ezeket az elemeket, valószínűleg NETSDK1022 buildelési hibát fog kapni. A hiba megoldásával kapcsolatos információkért lásd: NETSDK1022: Ismétlődő elemek szerepeltek.

Implicit használt direktívák

A .NET 6-tól kezdve implicit global using irányelvek jelennek meg az új C#-projektekben. Ez azt jelenti, hogy az ezekben a névterekben definiált típusokat anélkül használhatja, hogy meg kellene adnia a teljes nevet, vagy manuálisan kellene hozzáadnia egy using irányelvet. Az implicit szempont arra utal, hogy az global using irányelveket hozzáadják egy létrehozott fájlhoz a projekt obj könyvtárában.

Implicit global using irányelvek jelennek meg az alábbi SDK-k egyikét használó projektekhez:

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

A global using rendszer a projekt SDK-ján alapuló alapértelmezett névterek minden egyes névteréhez hozzáad egy direktívát. Ezek az alapértelmezett névterek az alábbi táblázatban láthatók.

SDK Alapértelmezett névterek
Microsoft.NET.Sdk System
System.Collections.Generic
System.IO
System.Linq
System.Net.Http
System.Threading
System.Threading.Tasks
Microsoft.NET.Sdk.Web Microsoft.NET.Sdk névterek
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 Microsoft.NET.Sdk névterek
Microsoft.Extensions.Configuration
Microsoft.Extensions.DependencyInjection
Microsoft.Extensions.Hosting
Microsoft.Extensions.Logging
Microsoft.NET.Sdk.WindowsDesktop (Windows Forms) Microsoft.NET.Sdk névterek
System.Drawing
System.Windows.Forms
Microsoft.NET.Sdk.WindowsDesktop (WPF) Microsoft.NET.Sdk névterek
Eltávolított System.IO
Eltávolított System.Net.Http

Ha le szeretné tiltani ezt a funkciót, vagy ha implicit irányelveket szeretne engedélyezni global using egy meglévő C#-projektben, ezt az ImplicitUsings MSBuild tulajdonságon keresztül teheti meg.

További implicit global using direktívák megadásához a projektfájlhoz elemeket adhat hozzá: Using elemeket (vagy Visual Basic-projektek esetén Import elemeket), például:

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

Feljegyzés

A .NET 8 SDK-tól System.Net.Http kezdve már nem szerepel a Microsoft.NET.Sdk .NET-keretrendszer célzásakor.

Implicit csomaghivatkozások

Amikor a projekt a .NET Standard 1.0-2.0-s verziót célozza, a .NET SDK implicit hivatkozásokat ad hozzá bizonyos metacsomagokhoz. A metacsomagok olyan keretrendszeralapú csomagok, amelyek csak más csomagoktól való függőségekből állnak. A metacsomagokra implicit módon hivatkozunk a projektfájl TargetFramework vagy TargetFrameworks (többes szám) tulajdonságában megadott cél-keretrendszerek alapján.

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

Szükség esetén letilthatja az implicit csomaghivatkozásokat a DisableImplicitFrameworkReferences tulajdonsággal, és explicit hivatkozásokat adhat hozzá csak a szükséges keretrendszerekhez vagy csomagokhoz.

Ajánlások:

  • Ha .NET-keretrendszer vagy .NET Standard 1.0-2.0-s verziót céloz meg, ne adjon hozzá explicit hivatkozást a NETStandard.Library metacsomagokra a projektfájl egyik <PackageReference> elemével. A .NET Standard 1.0-2.0-s projektek esetében ezekre a metacsomagokra implicit módon hivatkozunk. Ha .NET-keretrendszer projektek esetében a .NET Standard-alapú NuGet-csomag használatakor bármilyen verzióra NETStandard.Library van szükség, a NuGet automatikusan telepíti ezt a verziót.
  • Ha a .NET Standard 1.0-2.0-s verziójának megcélzásakor szüksége van a NETStandard.Library metacsomag adott verziójára, használhatja a <NetStandardImplicitPackageVersion> tulajdonságot, és beállíthatja a szükséges verziót.

Események létrehozása

SDK-stílusú projektekben használjon egy MSBuild célt PreBuild, vagy állítsa be a PostBuild tulajdonságot BeforeTargets, illetve a PreBuild tulajdonságot AfterTargets.

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

Feljegyzés

  • Az MSBuild-célok bármilyen nevet használhatnak. A Visual Studio IDE felismeri a PreBuild és PostBuild célokat, így ezeknek a neveknek a használatával szerkesztheti a parancsokat az IDE-ben.
  • A tulajdonságok PreBuildEventPostBuildEvent nem ajánlottak az SDK-stílusú projektekben, mert a makrók, például $(ProjectDir) nem oldódnak fel. A következő kód például nem támogatott:
<PropertyGroup>
  <PreBuildEvent>"$(ProjectDir)PreBuildEvent.bat" "$(ProjectDir)..\" "$(ProjectDir)" "$(TargetDir)"</PreBuildEvent>
</PropertyGroup>

A build testreszabása

A buildek testreszabásának különböző módjai vannak. Érdemes lehet felülbírálni egy tulajdonságot úgy, hogy argumentumként átadja az msbuild vagy dotnet parancsnak. A tulajdonságot a projektfájlhoz vagy a Directory.Build.props fájlhoz is hozzáadhatja. A .NET-projektek hasznos tulajdonságainak listáját az MSBuild .NET SDK-projektekre vonatkozó hivatkozásában találja.

Tipp.

Az új Directory.Build.props fájl parancssorból való létrehozásának egyszerű módja az adattár gyökerében található parancs dotnet new buildprops használata.

Egyéni célok

A .NET-projektek egyéni MSBuild-célokat és tulajdonságokat csomagolhatnak a csomagot használó projektek számára. Az alábbi bővíthetőségi típust használja a következő esetekben:

  • A buildelési folyamat kiterjesztése.
  • Hozzáférés a buildelési folyamat összetevőihez, például a létrehozott fájlokhoz.
  • Vizsgálja meg a build meghívásának konfigurációját.

Egyéni buildcélokat vagy tulajdonságokat úgy adhat hozzá, hogy a fájlokat <package_id>.targets vagy <package_id>.props formátumban (például Contoso.Utility.UsefulStuff.targets) elhelyezi a projekt build mappájában.

A következő XML egy .csproj fájlból származó kódrészlet, amely azt adja meg a dotnet pack parancsnak, hogy mit csomagoljon. Az <ItemGroup Label="dotnet pack instructions"> elem a célfájlokat a csomag 'build' mappájába helyezi. Az <Target Name="CollectRuntimeOutputs" BeforeTargets="_GetPackageFiles"> elem a szerelvényeket és .json fájlokat a buildmappába helyezi.

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

Ha egyéni célértéket szeretne használni a projektben, adjon hozzá egy PackageReference elemet, amely a csomagra és annak verziójára mutat. Az eszközökkel ellentétben az egyéni célcsomag a fogyasztó projekt függőségi zárása részét képezi.

Meghatározhatja, hogyan használja az egyéni célt. Mivel ez egy MSBuild-cél, függhet egy adott céltól, futtatható egy másik cél után, vagy manuálisan hívható meg a dotnet msbuild -t:<target-name> parancs használatával. A jobb felhasználói élmény érdekében azonban kombinálhatja a projektenkénti eszközöket és az egyéni célokat. Ebben a forgatókönyvben a projektenkénti eszköz elfogadja a szükséges paramétereket, és lefordítja azt a cél végrehajtásához szükséges dotnet msbuild meghívásra. Megtekinthet egy példát erre a szinergiára az MVP Summit 2016 Hackathon mintáinak repójában a projekt keretében.

Lásd még