.NET-projekt-SDK:er

Moderna .NET-projekt är associerade med ett programutvecklingspaket (SDK). Varje projekt-SDK är en uppsättning MSBuild-mål och associerade uppgifter som ansvarar för kompilering, paketering och publicering av kod. Ett projekt som refererar till ett projekt-SDK kallas ibland för ett SDK-liknande projekt.

Tillgängliga SDK:er

Följande SDK:er är tillgängliga:

ID beskrivning Lagringsplats
Microsoft.NET.Sdk .NET SDK 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 är bas-SDK för .NET. De andra SDK:erna refererar till .NET SDK och projekt som är associerade med de andra SDK:erna har alla .NET SDK-egenskaper tillgängliga för dem. Web SDK beror till exempel på både .NET SDK och Razor SDK.

Du kan också skapa en egen SDK som kan distribueras via NuGet.

För Windows Forms- och Windows Presentation Foundation-projekt (WPF) anger du .NET SDK (Microsoft.NET.Sdk) och anger några ytterligare egenskaper i projektfilen. Mer information finns i Aktivera .NET Desktop SDK.

Projektfiler

.NET-projekt baseras på MSBuild-formatet . Projektfiler, som har tillägg som .csproj för C#-projekt och .fsproj för F#-projekt, är i XML-format. Rotelementet i en MSBuild-projektfil är project-elementet . Elementet Project har ett valfritt Sdk attribut som anger vilken SDK (och version) som ska användas. Om du vill använda .NET-verktygen och skapa koden anger du Sdk attributet till ett av ID:na i tabellen Tillgängliga SDK:er .

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

Om du vill ange ett SDK som kommer från NuGet tar du med versionen i slutet av namnet eller anger namnet och versionen i filen global.json .

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

Ett annat sätt att ange SDK är med elementet på den översta nivån Sdk :

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

Om du refererar till ett SDK på något av dessa sätt förenklas projektfilerna för .NET avsevärt. När du utvärderar projektet lägger MSBuild till implicita importer överst Sdk.props i projektfilen och Sdk.targets längst ned.

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

Dricks

På en Windows-dator finns filerna Sdk.props och Sdk.targets i mappen %ProgramFiles%\dotnet\sdk\[version]\Sdks\Microsoft.NET.Sdk\Sdk .

Förbearbeta projektfilen

Du kan se det fullständigt expanderade projektet eftersom MSBuild ser det efter att SDK:t och dess mål har inkluderats med hjälp dotnet msbuild -preprocess av kommandot . Förbearbetningsväxeln för dotnet msbuild kommandot visar vilka filer som importeras, deras källor och deras bidrag till bygget utan att faktiskt skapa projektet.

Om projektet har flera målramverk fokuserar du bara kommandots resultat på ett ramverk genom att ange det som en MSBuild-egenskap. Till exempel:

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

Standard inkluderar och exkluderar

Standardvärdet inkluderar och exkluderar objektCompile, inbäddade resurser och None objekt definieras i SDK:t. Till skillnad från andra .NET Framework-projekt än SDK behöver du inte ange dessa objekt i projektfilen, eftersom standardvärdena omfattar de vanligaste användningsfallen. Det här beteendet gör projektfilen mindre och enklare att förstå och redigera för hand om det behövs.

I följande tabell visas vilka element och vilka glober som ingår och exkluderas i .NET SDK:

Element Inkludera glob Exkludera glob Ta bort glob
Compile **/*.cs (eller andra språktillägg) **/*.Användaren; **/*.*Proj; **/*.Sln; **/*.vssscc Ej tillämpligt
EmbeddedResource **/*.resx **/*.Användaren; **/*.*Proj; **/*.Sln; **/*.vssscc Ej tillämpligt
None **/* **/*.Användaren; **/*.*Proj; **/*.Sln; **/*.vssscc **/*.Cs; **/*.resx

Kommentar

Mapparna ./bin och ./obj , som representeras av $(BaseOutputPath) egenskaperna och $(BaseIntermediateOutputPath) MSBuild, undantas som standard från globerna. Exkluderingar representeras av egenskapen DefaultItemExcludes.

.NET Desktop SDK har ytterligare inkluderar och exkluderar för WPF. Mer information finns i WPF-standard inkluderar och exkluderar.

Om du uttryckligen definierar något av dessa objekt i projektfilen får du förmodligen ett NETSDK1022 build-fel. Information om hur du löser felet finns i NETSDK1022: Dubblettobjekt har inkluderats.

Implicit användning av direktiv

Från och med .NET 6 läggs implicita global using direktiv till i nya C#-projekt. Det innebär att du kan använda typer som definierats i dessa namnområden utan att behöva ange deras fullständigt kvalificerade namn eller lägga till ett using direktiv manuellt. Den implicita aspekten avser det faktum att direktiven global using läggs till i en genererad fil i projektets obj-katalog .

Implicita global using direktiv läggs till för projekt som använder någon av följande SDK:er:

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

Ett global using direktiv läggs till för varje namnområde i en uppsättning standardnamnområden som baseras på projektets SDK. Dessa standardnamnområden visas i följande tabell.

SDK Standardnamnområden
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-namnområden
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-namnområden
Microsoft.Extensions.Configuration
Microsoft.Extensions.DependencyInjection
Microsoft.Extensions.Hosting
Microsoft.Extensions.Logging
Microsoft.NET.Sdk.WindowsDesktop (Windows Forms) Microsoft.NET.Sdk-namnområden
System.Drawing
System.Windows.Forms
Microsoft.NET.Sdk.WindowsDesktop (WPF) Microsoft.NET.Sdk-namnområden
Bort System.IO
Bort System.Net.Http

Om du vill inaktivera den här funktionen eller om du vill aktivera implicita global using direktiv i ett befintligt C#-projekt kan du göra det via ImplicitUsings egenskapen MSBuild.

Du kan ange ytterligare implicita global using direktiv genom att lägga till Using objekt (eller Import objekt för Visual Basic-projekt) i projektfilen, till exempel:

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

Implicita paketreferenser

När projektet är avsett för .NET Standard 1.0-2.0 lägger .NET SDK till implicita referenser till vissa metapaket. Ett metapaket är ett ramverksbaserat paket som endast består av beroenden för andra paket. Metapaket refereras implicit baserat på de målramverk som anges i egenskapen TargetFramework eller TargetFrameworks (plural) för projektfilen.

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

Om det behövs kan du inaktivera implicita paketreferenser med egenskapen DisableImplicitFrameworkReferences och lägga till explicita referenser till bara de ramverk eller paket du behöver.

Rekommendationer:

  • När du riktar in dig på .NET Framework eller .NET Standard 1.0-2.0 ska du inte lägga till en explicit referens till metapaketen NETStandard.Library via ett <PackageReference> objekt i projektfilen. För .NET Standard 1.0-2.0-projekt refereras dessa metapaket implicit. För .NET Framework-projekt, om någon version av NETStandard.Library behövs när du använder ett .NET Standard-baserat NuGet-paket, installerar NuGet automatiskt den versionen.
  • Om du behöver en specifik version av NETStandard.Library metapaketet när du riktar in dig på .NET Standard 1.0-2.0 kan du använda <NetStandardImplicitPackageVersion> egenskapen och ange den version du behöver.

Skapa händelser

I SDK-projekt använder du ett MSBuild-mål med namnet PreBuild eller och anger BeforeTargets egenskapen för PreBuild eller AfterTargets egenskapen för 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>

Kommentar

  • Du kan använda valfritt namn för MSBuild-målen. Visual Studio IDE identifierar PreBuild och PostBuild mål, så genom att använda dessa namn kan du redigera kommandona i IDE.
  • Egenskaperna PreBuildEvent och PostBuildEvent rekommenderas inte i SDK-liknande projekt, eftersom makron som $(ProjectDir) inte är lösta. Följande kod stöds till exempel inte:
<PropertyGroup>
  <PreBuildEvent>"$(ProjectDir)PreBuildEvent.bat" "$(ProjectDir)..\" "$(ProjectDir)" "$(TargetDir)"</PreBuildEvent>
</PropertyGroup>

Anpassa versionen

Det finns olika sätt att anpassa en version. Du kanske vill åsidosätta en egenskap genom att skicka den som ett argument till kommandot msbuild eller dotnet . Du kan också lägga till egenskapen i projektfilen eller till en Directory.Build.props-fil. En lista över användbara egenskaper för .NET-projekt finns i MSBuild-referens för .NET SDK-projekt.

Dricks

Ett enkelt sätt att skapa en ny Directory.Build.props-fil från kommandoraden är att använda kommandot dotnet new buildprops i roten på lagringsplatsen.

Anpassade mål

.NET-projekt kan paketera anpassade MSBuild-mål och egenskaper för användning av projekt som använder paketet. Använd den här typen av utökningsbarhet när du vill:

  • Utöka byggprocessen.
  • Få åtkomst till artefakter i byggprocessen, till exempel genererade filer.
  • Granska konfigurationen under vilken bygget anropas.

Du lägger till anpassade byggmål eller egenskaper genom att placera filer i formuläret <package_id>.targets eller <package_id>.props (till exempel Contoso.Utility.UsefulStuff.targets) i byggmappen för projektet.

Följande XML är ett kodfragment från en .csproj-fil som instruerar dotnet pack kommandot vad som ska paketeras. Elementet <ItemGroup Label="dotnet pack instructions"> placerar målfilerna i byggmappen i paketet. Elementet <Target Name="CollectRuntimeOutputs" BeforeTargets="_GetPackageFiles"> placerar sammansättningarna och .json-filerna i byggmappen.

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

Om du vill använda ett anpassat mål i projektet lägger du till ett PackageReference element som pekar på paketet och dess version. Till skillnad från verktygen ingår paketet med anpassade mål i det förbrukande projektets beroendestängning.

Du kan konfigurera hur du använder det anpassade målet. Eftersom det är ett MSBuild-mål kan det bero på ett visst mål, köras efter ett annat mål eller anropas manuellt med hjälp dotnet msbuild -t:<target-name> av kommandot . Men för att ge en bättre användarupplevelse kan du kombinera verktyg per projekt och anpassade mål. I det här scenariot accepterar verktyget per projekt de parametrar som behövs och översätter det till det obligatoriska dotnet msbuild anrop som kör målet. Du kan se ett exempel på den här typen av synergieffekter på hackathon-lagringsplatsen MVP Summit 2016 i dotnet-packer projektet.

Se även