SDK de projet .NET
Les projets .NET modernes sont associés à un kit de développement logiciel (SDK). Chaque SDK de projet constitue un ensemble de cibles MSBuild et de tâches associées responsables de la compilation, de l’empaquetage et de la publication de code. Un projet qui fait référence à SDK est parfois appelé projet de style SDK.
Kits de développement logiciel (SDK) disponibles
Les kits SDK disponibles sont les suivants :
id | Description | Dépôt |
---|---|---|
Microsoft.NET.Sdk |
Le kit de développement logiciel (SDK) .NET | https://github.com/dotnet/sdk |
Microsoft.NET.Sdk.Web |
SDK web .NET | https://github.com/dotnet/sdk |
Microsoft.NET.Sdk.Razor |
SDK Razor .NET | https://github.com/dotnet/aspnetcore |
Microsoft.NET.Sdk.BlazorWebAssembly |
SDK Blazor WebAssembly | https://github.com/dotnet/aspnetcore |
Microsoft.NET.Sdk.Worker |
SDK Service Worker .NET | https://github.com/dotnet/aspnetcore |
Aspire.AppHost.Sdk |
Kit de développement logiciel (SDK) Aspire .NET | https://github.com/dotnet/aspire |
MSTest.Sdk |
Le SDK MSTest | https://github.com/microsoft/testfx |
Le SDK .NET est le SDK de base pour .NET. Les autres SDK font référence au SDK .NET et les projets associés aux autres SDK disposent de toutes les propriétés du SDK .NET. Le SDK web, par exemple, dépend du SDK .NET et du SDK Razor.
Pour les projets Windows Forms et Windows Presentation Foundation (WPF), vous spécifiez le kit de développement logiciel (SDK) .NET (Microsoft.NET.Sdk
) et définissez des propriétés supplémentaires dans le fichier projet. Pour plus d’informations, consultez Activer le kit de développement logiciel (SDK) .NET Desktop.
Les KITS SDK MSBuild, que vous pouvez utiliser pour configurer et étendre votre build, sont répertoriés dans les kits SDK MSBuild.
Vous avez également la possibilité de créer votre propre SDK qui peut être distribué via NuGet.
Fichiers projet
Les projets .NET sont basés sur le format MSBuild . Les fichiers projet, présentant des extensions telles que .csproj pour les projets C# et .fsproj pour les projets F#, sont au format XML. L’élément racine d’un fichier projet MSBuild correspond à l’élément Project. L’élément Project
possède un attribut facultatif Sdk
qui spécifie le SDK (et la version) à utiliser. Pour utiliser les outils .NET et générer votre code, définissez l’attribut Sdk
sur l’un des ID de la table SDK disponibles.
<Project Sdk="Microsoft.NET.Sdk">
<!-- Omitted for brevity... -->
</Project>
L’attribut et Sdk
l’élément Project/Sdk
activent des kits SDK additifs. Prenons l’exemple suivant, où le Kit de développement logiciel (SDK) Aspire .NET (Aspire.AppHost.Sdk
) est ajouté au projet en haut du Microsoft.NET.Sdk
projet :
<Project Sdk="Microsoft.NET.Sdk">
<Sdk Name="Aspire.AppHost.Sdk" Version="9.0.0" />
<!-- Omitted for brevity... -->
</Project>
Dans le fichier projet précédent, les deux kits SDK sont utilisés pour résoudre les dépendances dans une nature additive. Pour plus d’informations, consultez le Kit de développement logiciel (SDK) Aspire .NET
Pour spécifier un SDK provenant de NuGet, incluez la version à la fin du nom ou spécifiez le nom et la version dans le fichier global.json.
<Project Sdk="MSBuild.Sdk.Extras/2.0.54">
...
</Project>
L’élément de niveau supérieur Sdk
permet aussi de spécifier le kit de développement logiciel (SDK) :
<Project>
<Sdk Name="Microsoft.NET.Sdk" />
...
</Project>
Le référencement d’un SDK simplifie considérablement les fichiers projet pour .NET. Lors de l’évaluation du projet, MSBuild ajoute des importations implicites pour Sdk.props
en haut du fichier projet et Sdk.targets
en bas.
<Project>
<!-- Implicit top import -->
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
...
<!-- Implicit bottom import -->
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
</Project>
Conseil
Sur un ordinateur Windows, les fichiers Sdk.props et Sdk.targets sont disponibles dans le dossier %ProgramFiles%\dotnet\sdk\[version]\Sdks\Microsoft.NET.Sdk\Sdk.
Prétraiter le fichier projet
Vous pouvez voir le projet entièrement développé comme MSBuild le voit après inclusion du SDK et de ses cibles à l’aide de la commande dotnet msbuild -preprocess
. Le commutateur de prétraitement de la commande dotnet msbuild
indique les fichiers importés, leurs sources et leurs contributions à la build sans réellement générer le projet.
Si le projet comporte plusieurs versions cibles de .Net Framework, concentrez les résultats de la commande sur une seule d’entre elles en la spécifiant en tant que propriété MSBuild. Par exemple :
dotnet msbuild -property:TargetFramework=net8.0 -preprocess:output.xml
Inclusions et exclusions de la valeur par défaut
La valeur par défaut inclut et exclut les éléments Compile
, les ressources intégrées, et les éléments None
sont définis dans le kit de développement logiciel (SDK). Contrairement aux projets .NET Framework non SDK, vous n’avez pas besoin de spécifier ces éléments dans votre fichier projet, car les valeurs par défaut couvrent les cas d’usage les plus courants. Ce comportement réduit la taille du fichier projet et facilite sa compréhension et sa modification manuellement, si nécessaire.
Le tableau suivant indique les éléments et globs inclus et exclus dans le SDK .NET :
Élément | Inclure Glob | Exclure Glob | Supprimer Glob |
---|---|---|---|
Compile | **/*.cs (ou autres extensions de langage) | **/*.user; **/*.*proj; **/*.sln; **/*.vssscc | N/A |
EmbeddedResource | **/*.resx | **/*.user, **/*.*proj, **/*.sln, **/*.vssscc | N/A |
None | **/* | **/*.user, **/*.*proj, **/*.sln, **/*.vssscc | **/*.cs; **/*.resx |
Notes
Les dossiers ./bin
et ./obj
, représentés par les propriétés MSBuild $(BaseOutputPath)
et $(BaseIntermediateOutputPath)
, sont exclus des globs par défaut. Les exclusions sont représentées par la propriété DefaultItemExcludes.
Le kit de développement logiciel (SDK) .NET Desktop comporte des inclusions et des exclusions supplémentaires pour WPF. Pour plus d’informations, consultez Inclusions et exclusions WPF par défaut.
Si vous définissez explicitement l’un de ces éléments dans votre fichier projet, vous obtiendrez probablement une erreur de build NETSDK1022. Pour plus d’informations sur la résolution de l’erreur, consultez NETSDK1022 : Des éléments en double ont été inclus.
Directives d’utilisation implicites
À compter de .NET 6, des directives global using
implicites sont ajoutées aux nouveaux projets C#. Cela signifie que vous pouvez utiliser des types définis dans ces espaces de noms sans avoir à spécifier leur nom complet ou ajouter manuellement une directive using
. L’aspect implicite fait référence au fait que les directives global using
sont ajoutées à un fichier généré dans le répertoire obj du projet.
Les directives implicites global using
sont ajoutées pour les projets qui utilisent l’un des SDK suivants :
Microsoft.NET.Sdk
Microsoft.NET.Sdk.Web
Microsoft.NET.Sdk.Worker
Microsoft.NET.Sdk.WindowsDesktop
Une directive global using
est ajoutée pour chaque espace de noms dans un ensemble d’espaces de noms par défaut basés sur SDK du projet. Ces espaces de noms par défaut sont affichés dans le tableau suivant.
Kit SDK | Espaces de noms par défaut |
---|---|
Microsoft.NET.Sdk | System System.Collections.Generic System.IO System.Linq System.Net.Http System.Threading System.Threading.Tasks |
Microsoft.NET.Sdk.Web | Espaces de noms 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 | Espaces de noms Microsoft.NET.Sdk Microsoft.Extensions.Configuration Microsoft.Extensions.DependencyInjection Microsoft.Extensions.Hosting Microsoft.Extensions.Logging |
Microsoft.NET.Sdk.WindowsDesktop (Windows Forms) | Espaces de noms Microsoft.NET.Sdk System.Drawing System.Windows.Forms |
Microsoft.NET.Sdk.WindowsDesktop (WPF) | Espaces de noms Microsoft.NET.Sdk Suppression de System.IO Suppression de System.Net.Http |
Si vous souhaitez désactiver cette fonctionnalité ou activer des directives implicites global using
dans un projet C# existant, vous pouvez le faire via la propriété MSBuild ImplicitUsings
.
Vous pouvez spécifier des directives implicites global using
supplémentaires en ajoutant des éléments Using
(ou des éléments Import
pour les projets Visual Basic) à votre fichier projet, par exemple :
<ItemGroup>
<Using Include="System.IO.Pipes" />
</ItemGroup>
Remarque
À compter du Kit de développement logiciel (SDK) .NET 8, System.Net.Http il n’est plus inclus Microsoft.NET.Sdk
lors du ciblage du .NET Framework.
Références de package implicites
Lorsque votre projet cible .NET Standard 1.0-2.0, le kit de développement logiciel (SDK) .NET ajoute des références implicites à certains métapaquets. Un métapaquet est un package basé sur l’infrastructure qui se compose uniquement de dépendances portant sur d’autres packages. Les métapaquets sont référencés implicitement en fonction des versions cibles de .NET Framework spécifiées dans la propriété TargetFramework ou TargetFrameworks (au pluriel) de votre fichier projet.
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net462</TargetFrameworks>
</PropertyGroup>
Si nécessaire, vous pouvez désactiver les références de package implicites à l’aide de la propriété DisableImplicitFrameworkReferences et ajouter des références explicites aux seuls frameworks ou packages dont vous avez besoin.
Recommandations :
- Lorsque vous ciblez .NET Framework ou .NET Standard 1.0-2.0, n’ajoutez pas de référence explicite aux métapaquets
NETStandard.Library
via un élément<PackageReference>
de votre fichier projet. Pour les projets .NET Standard 1.0-2.0, ces métapaquets sont implicitement référencés. Pour les projets .NET Framework, si une version deNETStandard.Library
est nécessaire lors de l’utilisation d’un package NuGet basé sur .NET Standard, NuGet installe automatiquement cette version. - Si vous avez besoin d’une version spécifique du métapaquet
NETStandard.Library
quand vous ciblez .NET Standard 1.0-2.0, vous pouvez utiliser la propriété<NetStandardImplicitPackageVersion>
et définir la version dont vous avez besoin.
Événements de build
Dans les projets de style SDK, utilisez une cible MSBuild nommée PreBuild
ou PostBuild
et définissez la propriété BeforeTargets
pour PreBuild
ou la propriété AfterTargets
pour 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>
Notes
- Vous pouvez utiliser n’importe quel nom pour les cibles MSBuild. Toutefois, l’IDE Visual Studio reconnaît les cibles
PreBuild
etPostBuild
. Par conséquent, en utilisant ces noms, vous pouvez modifier les commandes dans l’IDE. - Les propriétés
PreBuildEvent
etPostBuildEvent
sont déconseillée pour les projets de style SDK, car les macros telles que$(ProjectDir)
ne sont pas résolues. Par exemple, le code suivant n’est pas pris en charge :
<PropertyGroup>
<PreBuildEvent>"$(ProjectDir)PreBuildEvent.bat" "$(ProjectDir)..\" "$(ProjectDir)" "$(TargetDir)"</PreBuildEvent>
</PropertyGroup>
Personnaliser la build
Il existe différentes façons de personnaliser une build. Vous pouvez remplacer une propriété en la transmettant en tant qu’argument à une commande msbuild ou dotnet. Vous pouvez également ajouter la propriété au fichier projet ou à un fichier Directory.Build.props. Pour obtenir la liste des propriétés utiles pour les projets .NET, consultez Référence MSBuild pour les projets SDK .NET.
Conseil
Utiliser la commande dotnet new buildprops
à la racine de votre référentiel permet de créer facilement un nouveau fichier Directory.Build.props à partir de la ligne de commande.
Cibles personnalisées
Les projets .NET peuvent empaqueter des cibles et des propriétés MSBuild personnalisées à utiliser par les projets qui consomment le package. Utilisez ce type d’extensibilité lorsque vous souhaitez :
- Étendre le processus de génération.
- Accéder aux artefacts du processus de génération, tels que les fichiers générés.
- Inspecter la configuration sous laquelle la build est appelée.
Vous ajoutez des cibles ou des propriétés de build personnalisées en plaçant des fichiers dans le formulaire <package_id>.targets
ou <package_id>.props
(par exemple, Contoso.Utility.UsefulStuff.targets
) dans le dossier de build du projet.
Le code XML suivant est un extrait de code de fichier .csproj qui indique à la commande dotnet pack
les éléments à empaqueter. L’élément <ItemGroup Label="dotnet pack instructions">
place les fichiers cibles dans le dossier de build à l’intérieur du package. L’élément <Target Name="CollectRuntimeOutputs" BeforeTargets="_GetPackageFiles">
place les assemblys et les fichiers .json dans le dossier de build.
<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>
Pour utiliser une cible personnalisée dans votre projet, ajoutez un élément PackageReference
qui pointe vers le package et sa version. Contrairement aux outils, le package des cibles personnalisées est inclus dans la fermeture de dépendance du projet de consommation.
Vous pouvez configurer l’utilisation de la cible personnalisée. Puisqu’il s’agit d’une cible MSBuild, elle peut dépendre d’une cible donnée, exécutée après une autre cible, ou peut être appelée manuellement à l’aide de la commande dotnet msbuild -t:<target-name>
. Toutefois, pour une meilleure expérience utilisateur, vous pouvez combiner des outils par projet et des cibles personnalisées. Dans ce scénario, l’outil par projet accepte tous les paramètres nécessaires et les convertit en appel dotnet msbuild
requis qui exécute la cible. Vous pouvez voir un exemple de ce type de synergie sur le dépôt des exemples du MVP Summit 2016 Hackathon du projet dotnet-packer
.