.NET-projekt-SDK:er
Moderna .NET-projekt är associerade med ett SDK (Project Software Development Kit). 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.Razor |
.NET Razor SDK | https://github.com/dotnet/aspnetcore |
Microsoft.NET.Sdk.BlazorWebAssembly |
The .NET Blazor WebAssembly SDK | https://github.com/dotnet/aspnetcore |
Microsoft.NET.Sdk.Worker |
.NET Worker Service SDK | |
Aspire.AppHost.Sdk |
The .NET Aspire SDK | https://github.com/dotnet/aspire |
MSTest.Sdk |
MSTest SDK | https://github.com/microsoft/testfx |
.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>
Från och med .NET Aspire 9 kan föregående exempel i stället använda .NET Aspire SDK.
<Project Sdk="Microsoft.NET.Sdk">
<Sdk Name="Aspire.AppHost.Sdk" Version="9.0.0-rc.1.24511.1" />
<!-- Omitted for brevity... -->
</Project>
Mer information finns i .NET Aspire-verktyg och konfiguration.
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ändare; **/*.*proj; **/*.sln; **/*.vssscc | Ej tillämpligt |
EmbeddedResource | **/*.resx | **/*.användare; **/*.*proj; **/*.sln; **/*.vssscc | Ej tillämpligt |
None | **/* | **/*.användare; **/*.*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 Avlägsnad System.IO Avlägsnad 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 avNETStandard.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 PostBuild
PostBuild
.
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Exec Command=""$(ProjectDir)PreBuildEvent.bat" "$(ProjectDir)..\" "$(ProjectDir)" "$(TargetDir)"" />
</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
ochPostBuild
mål, så genom att använda dessa namn kan du redigera kommandona i IDE. - Egenskaperna
PreBuildEvent
ochPostBuildEvent
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.