.NET-project-SDK's
Moderne .NET-projecten zijn gekoppeld aan een project software development kit (SDK). Elke project-SDK is een set MSBuild-doelen en bijbehorende taken die verantwoordelijk zijn voor het compileren, verpakken en publiceren van code. Een project dat verwijst naar een project-SDK wordt soms een SDK-project genoemd.
Beschikbare SDK's
De beschikbare SDK's zijn:
Id | Beschrijving | Opslagplaats |
---|---|---|
Microsoft.NET.Sdk |
De .NET-SDK | https://github.com/dotnet/sdk |
Microsoft.NET.Sdk.Web |
De .NET Web SDK | https://github.com/dotnet/sdk |
Microsoft.NET.Sdk.Razor |
De .NET Razor SDK | https://github.com/dotnet/aspnetcore |
Microsoft.NET.Sdk.BlazorWebAssembly |
De .NET Blazor WebAssembly SDK | https://github.com/dotnet/aspnetcore |
Microsoft.NET.Sdk.Worker |
De .NET Worker Service SDK | https://github.com/dotnet/aspnetcore |
Aspire.AppHost.Sdk |
De .NET Aspire SDK | https://github.com/dotnet/aspire |
MSTest.Sdk |
De MSTest SDK | https://github.com/microsoft/testfx |
De .NET SDK is de basis-SDK voor .NET. De andere SDK's verwijzen naar de .NET SDK en projecten die aan de andere SDK's zijn gekoppeld, hebben alle .NET SDK-eigenschappen die voor hen beschikbaar zijn. De Web-SDK is bijvoorbeeld afhankelijk van zowel de .NET SDK als de Razor-SDK.
Voor WPF-projecten (Windows Forms en Windows Presentation Foundation) geeft u de .NET SDK (Microsoft.NET.Sdk
) op en stelt u enkele extra eigenschappen in het projectbestand in. Zie .NET Desktop SDK inschakelen voor meer informatie.
MSBuild SDK's, die u kunt gebruiken om uw build te configureren en uit te breiden, worden vermeld bij MSBuild SDK's.
U kunt ook uw eigen SDK ontwerpen die kan worden gedistribueerd via NuGet.
Projectbestanden
.NET-projecten zijn gebaseerd op de MSBuild-indeling . Projectbestanden, die extensies hebben zoals .csproj voor C#-projecten en .fsproj voor F#-projecten, hebben een XML-indeling. Het hoofdelement van een MSBuild-projectbestand is het projectelement . Het Project
element heeft een optioneel Sdk
kenmerk dat aangeeft welke SDK (en versie) moet worden gebruikt. Als u de .NET-hulpprogramma's wilt gebruiken en uw code wilt bouwen, stelt u het Sdk
kenmerk in op een van de id's in de tabel Beschikbare SDK's .
<Project Sdk="Microsoft.NET.Sdk">
<!-- Omitted for brevity... -->
</Project>
Het Project/Sdk
kenmerk en Sdk
element maken additieve SDK's mogelijk. Bekijk het volgende voorbeeld, waarbij de .NET Aspire SDK (Aspire.AppHost.Sdk
) wordt toegevoegd aan het project bovenaan het Microsoft.NET.Sdk
:
<Project Sdk="Microsoft.NET.Sdk">
<Sdk Name="Aspire.AppHost.Sdk" Version="9.0.0" />
<!-- Omitted for brevity... -->
</Project>
In het voorgaande projectbestand worden beide SDK's gebruikt om afhankelijkheden in een additief karakter op te lossen. Zie .NET Aspire SDK voor meer informatie
Als u een SDK wilt opgeven die afkomstig is van NuGet, neemt u de versie op aan het einde van de naam of geeft u de naam en versie op in het global.json-bestand .
<Project Sdk="MSBuild.Sdk.Extras/2.0.54">
...
</Project>
Een andere manier om de SDK op te geven, is met het element op het hoogste niveau Sdk
:
<Project>
<Sdk Name="Microsoft.NET.Sdk" />
...
</Project>
Het verwijzen naar een SDK op een van deze manieren vereenvoudigt aanzienlijk projectbestanden voor .NET. Tijdens het evalueren van het project voegt MSBuild impliciete importbewerkingen toe voor Sdk.props
boven aan het projectbestand en Sdk.targets
onderaan.
<Project>
<!-- Implicit top import -->
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
...
<!-- Implicit bottom import -->
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
</Project>
Tip
Op een Windows-computer vindt u de sdk.props - en Sdk.targets-bestanden in de map %ProgramFiles%\dotnet\sdk\[version]\Sdks\Microsoft.NET.Sdk\Sdk .
Het projectbestand vooraf verwerken
U kunt het volledig uitgevouwen project zien zoals MSBuild het ziet nadat de SDK en de bijbehorende doelen zijn opgenomen met behulp van de dotnet msbuild -preprocess
opdracht. De schakeloptie voorverwerking van de dotnet msbuild
opdracht laat zien welke bestanden worden geïmporteerd, hun bronnen en hun bijdragen aan de build zonder het project daadwerkelijk te bouwen.
Als het project meerdere doelframeworks heeft, richt u de resultaten van de opdracht op slechts één framework door het op te geven als een MSBuild-eigenschap. Voorbeeld:
dotnet msbuild -property:TargetFramework=net8.0 -preprocess:output.xml
Standaard bevat en sluit deze uit
De standaardinstellingen omvatten en uitsluiten voor Compile
items, ingesloten resources en None
items worden gedefinieerd in de SDK. In tegenstelling tot niet-SDK .NET Framework-projecten hoeft u deze items niet op te geven in uw projectbestand, omdat de standaardinstellingen betrekking hebben op de meest voorkomende gebruiksvoorbeelden. Dit gedrag maakt het projectbestand kleiner en gemakkelijker te begrijpen en te bewerken, indien nodig.
In de volgende tabel ziet u welke elementen en welke globs worden opgenomen en uitgesloten in de .NET SDK:
Element | Voeg een glob toe | Glob uitsluiten | Glob verwijderen |
---|---|---|---|
Compile | **/*.cs (of andere taalextensies) | **/*.gebruiker; **/*.*proj; **/*.sln; **/*.vssscc | N.v.t. |
EmbeddedResource | **/*.resx | **/*.gebruiker; **/*.*proj; **/*.sln; **/*.vssscc | N.v.t. |
None | **/* | **/*.gebruiker; **/*.*proj; **/*.sln; **/*.vssscc | **/*.Cs; **/*.resx |
Notitie
De ./bin
mappen en ./obj
mappen, die worden vertegenwoordigd door de $(BaseOutputPath)
eigenschappen en $(BaseIntermediateOutputPath)
MSBuild, worden standaard uitgesloten van de globs. Uitsluitingen worden vertegenwoordigd door de eigenschap DefaultItemExcludes.
De .NET Desktop SDK bevat extra inclusief en uitgesloten voor WPF. Zie WPF-standaardinstellingen voor in- en uitsluiten voor meer informatie.
Als u een van deze items expliciet definieert in uw projectbestand, krijgt u waarschijnlijk een NETSDK1022 buildfout. Zie NETSDK1022: Dubbele items zijn opgenomen voor informatie over het oplossen van de fout.
Impliciet gebruik van instructies
Vanaf .NET 6 worden impliciete global using
instructies toegevoegd aan nieuwe C#-projecten. Dit betekent dat u typen kunt gebruiken die in deze naamruimten zijn gedefinieerd zonder dat u hun volledig gekwalificeerde naam hoeft op te geven of handmatig een using
instructie hoeft toe te voegen. Het impliciete aspect verwijst naar het feit dat de global using
richtlijnen worden toegevoegd aan een gegenereerd bestand in de obj-map van het project.
Impliciete global using
instructies worden toegevoegd voor projecten die gebruikmaken van een van de volgende SDK's:
Microsoft.NET.Sdk
Microsoft.NET.Sdk.Web
Microsoft.NET.Sdk.Worker
Microsoft.NET.Sdk.WindowsDesktop
global using
Er wordt een instructie toegevoegd voor elke naamruimte in een set standaardnaamruimten die zijn gebaseerd op de SDK van het project. Deze standaardnaamruimten worden weergegeven in de volgende tabel.
SDK | Standaardnaamruimten |
---|---|
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-naamruimten 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-naamruimten Microsoft.Extensions.Configuration Microsoft.Extensions.DependencyInjection Microsoft.Extensions.Hosting Microsoft.Extensions.Logging |
Microsoft.NET.Sdk.WindowsDesktop (Windows Forms) | Microsoft.NET.Sdk-naamruimten System.Drawing System.Windows.Forms |
Microsoft.NET.Sdk.WindowsDesktop (WPF) | Microsoft.NET.Sdk-naamruimten Verwijderd System.IO Verwijderd System.Net.Http |
Als u deze functie wilt uitschakelen of als u impliciete global using
instructies in een bestaand C#-project wilt inschakelen, kunt u dit doen via de ImplicitUsings
eigenschap MSBuild.
U kunt aanvullende impliciete global using
instructies opgeven door items (of Import
items voor Visual Basic-projecten) toe te voegen Using
aan uw projectbestand, bijvoorbeeld:
<ItemGroup>
<Using Include="System.IO.Pipes" />
</ItemGroup>
Notitie
Beginnend met de .NET 8 SDK, System.Net.Http wordt niet meer opgenomen in Microsoft.NET.Sdk
het doel van .NET Framework.
Impliciete pakketverwijzingen
Wanneer uw project is gericht op .NET Standard 1.0-2.0, voegt de .NET SDK impliciete verwijzingen toe aan bepaalde metapackages. Een metapackage is een framework-pakket dat alleen bestaat uit afhankelijkheden van andere pakketten. Metapackages worden impliciet verwezen op basis van de doelframeworks die zijn opgegeven in de eigenschap TargetFramework of TargetFrameworks (meervoud) van uw projectbestand.
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net462</TargetFrameworks>
</PropertyGroup>
Indien nodig kunt u impliciete pakketverwijzingen uitschakelen met behulp van de eigenschap DisableImplicitFrameworkReferences en expliciete verwijzingen toevoegen aan alleen de frameworks of pakketten die u nodig hebt.
Aanbevelingen:
- Als u zich richt op .NET Framework of .NET Standard 1.0-2.0, voegt u geen expliciete verwijzing naar de
NETStandard.Library
metapackages toe via een<PackageReference>
item in uw projectbestand. Voor .NET Standard 1.0-2.0-projecten wordt impliciet verwezen naar deze metapackages. Voor .NET Framework-projecten, als er een versie van nodig is bij het gebruik van een NuGet-pakket op basis vanNETStandard.Library
.NET Standard, installeert NuGet die versie automatisch. - Als u een specifieke versie van de
NETStandard.Library
metapackage nodig hebt bij het doel van .NET Standard 1.0-2.0, kunt u de<NetStandardImplicitPackageVersion>
eigenschap gebruiken en de versie instellen die u nodig hebt.
Build-gebeurtenissen
Gebruik in SDK-projecten een MSBuild-doel met de naam of stel de BeforeTargets
eigenschap voor PreBuild
of de AfterTargets
eigenschap voor PostBuild
.PostBuild
PreBuild
<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>
Notitie
- U kunt elke naam gebruiken voor de MSBuild-doelen. De Visual Studio IDE herkent
PreBuild
enPostBuild
doelen, dus met deze namen kunt u de opdrachten in de IDE bewerken. - De eigenschappen
PreBuildEvent
enPostBuildEvent
worden niet aanbevolen in SDK-projecten, omdat macro's zoals$(ProjectDir)
niet worden opgelost. De volgende code wordt bijvoorbeeld niet ondersteund:
<PropertyGroup>
<PreBuildEvent>"$(ProjectDir)PreBuildEvent.bat" "$(ProjectDir)..\" "$(ProjectDir)" "$(TargetDir)"</PreBuildEvent>
</PropertyGroup>
De build aanpassen
Er zijn verschillende manieren om een build aan te passen. U kunt een eigenschap overschrijven door deze als argument door te geven aan de opdracht msbuild of dotnet . U kunt de eigenschap ook toevoegen aan het projectbestand of aan een map.build.props-bestand. Zie MSBuild-referentie voor .NET SDK-projecten voor een lijst met nuttige eigenschappen voor .NET-projecten.
Tip
Een eenvoudige manier om een nieuw bestand Directory.Build.props te maken vanaf de opdrachtregel is met behulp van de opdracht dotnet new buildprops
in de hoofdmap van uw opslagplaats.
Aangepaste doelen
.NET-projecten kunnen aangepaste MSBuild-doelen en -eigenschappen verpakken voor gebruik door projecten die het pakket gebruiken. Gebruik dit type uitbreidbaarheid als u het volgende wilt doen:
- Breid het buildproces uit.
- Toegang tot artefacten van het buildproces, zoals gegenereerde bestanden.
- Controleer de configuratie waaronder de build wordt aangeroepen.
U voegt aangepaste builddoelen of -eigenschappen toe door bestanden in het formulier <package_id>.targets
of (bijvoorbeeldContoso.Utility.UsefulStuff.targets
) in de buildmap van het <package_id>.props
project te plaatsen.
De volgende XML is een fragment uit een .csproj-bestand waarmee de dotnet pack
opdracht wordt geïnstrueerd wat moet worden verpakt. Het <ItemGroup Label="dotnet pack instructions">
element plaatst de doelbestanden in de buildmap in het pakket. Het <Target Name="CollectRuntimeOutputs" BeforeTargets="_GetPackageFiles">
element plaatst de assembly's en .json bestanden in de buildmap .
<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>
Als u een aangepast doel in uw project wilt gebruiken, voegt u een PackageReference
element toe dat verwijst naar het pakket en de bijbehorende versie. In tegenstelling tot de hulpprogramma's wordt het aangepaste doelenpakket opgenomen in de afhankelijkheidssluiting van het verbruikende project.
U kunt configureren hoe u het aangepaste doel gebruikt. Omdat het een MSBuild-doel is, kan het afhankelijk zijn van een bepaald doel, na een ander doel worden uitgevoerd of handmatig worden aangeroepen met behulp van de dotnet msbuild -t:<target-name>
opdracht. Als u echter een betere gebruikerservaring wilt bieden, kunt u hulpprogramma's en aangepaste doelen per project combineren. In dit scenario accepteert het hulpprogramma per project de parameters die nodig zijn en vertaalt dit in de vereiste dotnet msbuild
aanroep waarmee het doel wordt uitgevoerd. U kunt een voorbeeld van dit soort synergie zien op de MVP Summit 2016 Hackathon samples repo in het dotnet-packer
project.