Remarque
L’accès à cette page requiert une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page requiert une autorisation. Vous pouvez essayer de modifier des répertoires.
Cet article explique comment écrire des bibliothèques pour .NET à l’aide de l’interface CLI .NET. L’interface CLI fournit une expérience efficace et de bas niveau qui fonctionne sur tous les systèmes d’exploitation pris en charge. Vous pouvez toujours créer des bibliothèques avec Visual Studio, et si c'est votre expérience préférée refer au guide de Visual Studio.
Prérequis
Vous avez besoin du sdk .NET installé sur votre ordinateur.
Pour les sections de ce document traitant des versions de .NET Framework, vous avez besoin de la .NET Framework installée sur un ordinateur Windows.
En outre, si vous souhaitez prendre en charge des cibles de .NET Framework plus anciennes, vous devez installer des packs de ciblage ou des packs de développement à partir de la page de téléchargements .NET Framework. Reportez-vous au tableau suivant :
| version de .NET Framework | Ce qu'il faut télécharger |
|---|---|
| 4.6.1 | pack de ciblage .NET Framework 4.6.1 |
| 4.6 | pack de ciblage .NET Framework 4.6 |
| 4.5.2 | .NET Framework 4.5.2 Kit de Développement |
| 4.5.1 | .NET Framework 4.5.1 Developer Pack |
| 4.5 | Kit de développement logiciel Windows pour Windows 8 |
| 4.0 | sdk Windows pour Windows 7 et .NET Framework 4 |
| 2.0, 3.0 et 3.5 | .NET Framework 3.5 SP1 Runtime (ou version Windows 8+ ) |
Comment cibler .NET 5+ ou .NET Standard
Vous contrôlez le framework cible de votre projet en l’ajoutant à votre fichier projet (.csproj ou .fsproj). Pour obtenir des conseils sur la façon de choisir entre le ciblage .NET 5+ ou .NET Standard, consultez .NET 5+ et .NET Standard.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
</Project>
Si vous souhaitez cibler .NET Framework versions 4.0 ou ultérieures, ou si vous souhaitez utiliser une API disponible dans .NET Framework, mais pas dans .NET Standard (par exemple, System.Drawing), lisez les sections suivantes et découvrez comment multitarget.
Guide pratique pour cibler .NET Framework
Note
Ces instructions supposent que vous avez installé .NET Framework sur votre ordinateur. Consultez les prérequis pour installer les dépendances.
N’oubliez pas que certaines des versions .NET Framework utilisées ici ne sont plus prises en charge. Consultez la FAQ sur la politique de support du cycle de vie .NET Framework concernant les versions non prises en charge.
Si vous souhaitez atteindre le nombre maximal de développeurs et de projets, utilisez .NET Framework 4.0 comme cible de référence. Pour cibler .NET Framework, commencez par utiliser le moniker de framework cible approprié (TFM) qui correspond à la version de .NET Framework que vous souhaitez prendre en charge.
| version de .NET Framework | TFM |
|---|---|
| .NET Framework 2.0 | net20 |
| .NET Framework 3.0 | net30 |
| .NET Framework 3.5 | net35 |
| .NET Framework 4.0 | net40 |
| .NET Framework 4.5 | net45 |
| .NET Framework 4.5.1 | net451 |
| .NET Framework 4.5.2 | net452 |
| .NET Framework 4.6 | net46 |
| .NET Framework 4.6.1 | net461 |
| .NET Framework 4.6.2 | net462 |
| .NET Framework 4.7 | net47 |
| .NET Framework 4.8 | net48 |
Insérez ensuite le TFM dans la section appropriée de votre fichier projet. Par exemple, voici comment écrire une bibliothèque qui cible .NET Framework 4.0 :
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net40</TargetFramework>
</PropertyGroup>
</Project>
C’est tout ! Bien que cela soit compilé uniquement pour .NET Framework 4, vous pouvez utiliser la bibliothèque sur les versions plus récentes de .NET Framework.
Comment réaliser un multiciblage
Note
Les instructions suivantes supposent que vous avez installé .NET Framework sur votre ordinateur. Reportez-vous à la section Prérequis pour savoir quelles dépendances doivent être installées et à partir d’où les télécharger.
Vous devrez peut-être cibler des versions antérieures de l’infrastructure .NET lorsque votre projet prend en charge à la fois l’infrastructure .NET et les .NET. Dans ce scénario, si vous voulez utiliser des API et des constructions de langage plus récentes pour des cibles plus récentes, utilisez des directives dans votre code. Vous pouvez aussi avoir besoin d’ajouter différents packages et différentes dépendances pour chaque plateforme que vous ciblez pour inclure les différentes API nécessaires à chaque cas.
Supposons, par exemple, que vous avez une bibliothèque qui effectue des opérations réseau sur HTTP. Pour .NET Standard et les versions .NET Framework 4.5 ou ultérieures, vous pouvez utiliser la classe HttpClient à partir de l’espace de noms System.Net.Http. Toutefois, les versions antérieures de .NET Framework n'ont pas la classe HttpClient. Vous pouvez donc utiliser la classe WebClient à partir de l'espace de noms System.Net pour celles-ci.
Voici à quoi peut ressembler votre fichier projet :
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net40;net45</TargetFrameworks>
</PropertyGroup>
<!-- Need to conditionally bring in references for the .NET Framework 4.0 target -->
<ItemGroup Condition="'$(TargetFramework)' == 'net40'">
<Reference Include="System.Net" />
</ItemGroup>
<!-- Need to conditionally bring in references for the .NET Framework 4.5 target -->
<ItemGroup Condition="'$(TargetFramework)' == 'net45'">
<Reference Include="System.Net.Http" />
<Reference Include="System.Threading.Tasks" />
</ItemGroup>
</Project>
Notez trois changements majeurs ici :
- Le nœud
a été remplacé par , et trois TFMs (Monikers du Framework cible) sont exprimés à l'intérieur. - Il existe un nœud
<ItemGroup>pour la ciblenet40, incluant une référence .NET Framework. - Il existe un nœud
<ItemGroup>pour la ciblenet45avec deux références au Framework .NET.
Symboles du préprocesseur
Le système de build est informé des symboles de préprocesseur suivants utilisés dans les directives :
| Versions cibles de .NET Framework | symboles | Symboles supplémentaires (disponible dans les sdk .NET 5+ ) |
Symboles de plateforme (disponibles uniquement lorsque vous spécifiez un nom spécifique pour le framework cible propre au système d’exploitation) |
|---|---|---|---|
| Framework .NET | , , , , , , , , , , , , , , | , , , , , , , , , , , , | |
| .NET Standard | , , , , , , , , , | , , , , , , , | |
| .NET 5+ (et .NET Core) | , , , , , , , , , , , , , , | , , , , , , | , , , , , , (par exemple, ), (par exemple ) |
Note
- Les symboles sans version sont définis indépendamment de la version que vous ciblez.
- Les symboles spécifiques à la version sont définis uniquement pour la version que vous ciblez.
- Les symboles sont définis pour la version que vous ciblez et toutes les versions antérieures. Par exemple, si vous ciblez .NET Framework 2.0, les symboles suivants sont définis :
NET20,NET20_OR_GREATER,NET11_OR_GREATERetNET10_OR_GREATER. - Les symboles
NETSTANDARD<x>_<y>_OR_GREATERsont définis uniquement pour les cibles standard .NET, et non pour les cibles qui implémentent .NET Standard, telles que .NET Core et .NET Framework. - Ils diffèrent des monikers de framework cible employés par la propriété MSBuild et par NuGet.
Voici un exemple d’utilisation de la compilation conditionnelle par cible :
using System;
using System.Text.RegularExpressions;
#if NET40
// This only compiles for the .NET Framework 4 targets
using System.Net;
#else
// This compiles for all other targets
using System.Net.Http;
using System.Threading.Tasks;
#endif
namespace MultitargetLib
{
public class Library
{
#if NET40
private readonly WebClient _client = new WebClient();
private readonly object _locker = new object();
#else
private readonly HttpClient _client = new HttpClient();
#endif
#if NET40
// .NET Framework 4.0 does not have async/await
public string GetDotNetCount()
{
string url = "https://www.dotnetfoundation.org/";
var uri = new Uri(url);
string result = "";
// Lock here to provide thread-safety.
lock(_locker)
{
result = _client.DownloadString(uri);
}
int dotNetCount = Regex.Matches(result, ".NET").Count;
return $"Dotnet Foundation mentions .NET {dotNetCount} times!";
}
#else
// .NET Framework 4.5+ can use async/await!
public async Task<string> GetDotNetCountAsync()
{
string url = "https://www.dotnetfoundation.org/";
// HttpClient is thread-safe, so no need to explicitly lock here
var result = await _client.GetStringAsync(url);
int dotNetCount = Regex.Matches(result, ".NET").Count;
return $"dotnetfoundation.org mentions .NET {dotNetCount} times in its HTML!";
}
#endif
}
}
Si vous générez ce projet avec , notez la présence de trois répertoires sous le dossier :
net40/
net45/
netstandard2.0/
Chacun d’entre eux contient les fichiers pour chaque cible.
Guide pratique pour tester des bibliothèques sur .NET
Il est important de pouvoir effectuer des tests sur plusieurs plateformes. Vous pouvez utiliser xUnit ou MSTest dans leur version d’origine. Les deux sont parfaitement adaptés aux tests unitaires de votre bibliothèque sur .NET. La façon dont vous configurez votre solution avec des projets de test dépend de la structure de votre solution. L’exemple suivant part du principe que les répertoires de test et source résident dans le même répertoire de premier niveau.
Note
Cela utilise des commandes .NET CLI. Pour plus d’informations, consultez dotnet new et dotnet sln.
Configurez votre solution. Pour cela, utilisez la commande suivante :
mkdir SolutionWithSrcAndTest cd SolutionWithSrcAndTest dotnet new sln dotnet new classlib -o MyProject dotnet new xunit -o MyProject.Test dotnet sln add MyProject/MyProject.csproj dotnet sln add MyProject.Test/MyProject.Test.csprojCette commande crée des projets et les relie dans une solution. Votre répertoire pour doit ressembler à ceci :
/SolutionWithSrcAndTest |__SolutionWithSrcAndTest.sln |__MyProject/ |__MyProject.Test/Accédez au répertoire du projet de test et ajoutez une référence à à partir de .
cd MyProject.Test dotnet reference add ../MyProject/MyProject.csprojRestaurez les packages et construisez les projets.
dotnet restore dotnet buildExécutez la commande pour vérifier que xUnit s’exécute. Si vous avez choisi d’utiliser MSTest, le Test Runner de console MSTest doit s’exécuter à la place.
C’est tout ! Vous pouvez maintenant tester votre bibliothèque sur toutes les plateformes à l’aide des outils en ligne de commande. Maintenant que vous avez tout configuré, le test de votre bibliothèque est très simple :
- Apportez des modifications à votre bibliothèque.
- Exécutez les tests à partir de la ligne de commande, dans votre répertoire de test, avec la commande .
Votre code est automatiquement régénéré quand vous appelez la commande .
Comment utiliser plusieurs projets
Les bibliothèques plus volumineuses ont souvent besoin de placer des fonctionnalités dans différents projets.
Imaginez que vous vouliez créer une bibliothèque de code pouvant être utilisée de manière idiomatique en C# et F#. Cela signifierait que les consommateurs de votre bibliothèque la consomment de manière naturelle en C# ou F#. Par exemple, en C#, vous pouvez utiliser la bibliothèque de la façon suivante :
using AwesomeLibrary.CSharp;
public Task DoThings(Data data)
{
var convertResult = await AwesomeLibrary.ConvertAsync(data);
var result = AwesomeLibrary.Process(convertResult);
// do something with result
}
En F#, le code peut se présenter comme suit :
open AwesomeLibrary.FSharp
let doWork data = async {
let! result = AwesomeLibrary.AsyncConvert data // Uses an F# async function rather than C# async method
// do something with result
}
Les scénarios de consommation tels que celui-ci signifient que les API auxquelles vous accédez ont une structure différente en C# et F#. Pour réaliser ceci, il est courant de factoriser toute la logique d’une bibliothèque dans un projet principal et d’avoir des projets C# et F# définissant les couches API qui effectuent des appels à ce projet principal. Le reste de la section utilise les noms suivants :
- AwesomeLibrary.Core : projet principal qui contient toute la logique de la bibliothèque
- AwesomeLibrary.CSharp : projet avec des API publiques destinées à être consommées en C#
- AwesomeLibrary.CSharp : projet avec des API publiques destinées à être consommées en F#
Vous pouvez exécuter les commandes suivantes dans votre terminal pour produire la même structure que ce guide :
mkdir AwesomeLibrary && cd AwesomeLibrary
dotnet new sln
mkdir AwesomeLibrary.Core && cd AwesomeLibrary.Core && dotnet new classlib
cd ..
mkdir AwesomeLibrary.CSharp && cd AwesomeLibrary.CSharp && dotnet new classlib
cd ..
mkdir AwesomeLibrary.FSharp && cd AwesomeLibrary.FSharp && dotnet new classlib -lang "F#"
cd ..
dotnet sln add AwesomeLibrary.Core/AwesomeLibrary.Core.csproj
dotnet sln add AwesomeLibrary.CSharp/AwesomeLibrary.CSharp.csproj
dotnet sln add AwesomeLibrary.FSharp/AwesomeLibrary.FSharp.fsproj
Cette opération ajoute les trois projets ci-dessus et un fichier solution qui les relie. Le fait de créer le fichier solution et de lier des projets vous permet de restaurer et de générer des projets à partir d’un niveau supérieur.
Références entre projets
La meilleure façon de référencer un projet consiste à utiliser l’interface CLI .NET pour ajouter une référence de projet. À partir des répertoires de projet AwesomeLibrary.CSharp et de AwesomeLibrary.FSharp, vous pouvez exécuter la commande suivante :
dotnet reference add ../AwesomeLibrary.Core/AwesomeLibrary.Core.csproj
Les fichiers projet pour AwesomeLibrary.CSharp et AwesomeLibrary.FSharp référencent désormais AwesomeLibrary.Core comme cible. Pour le vérifier, confirmez la présence des éléments suivants dans les fichiers projet :
<ItemGroup>
<ProjectReference Include="..\AwesomeLibrary.Core\AwesomeLibrary.Core.csproj" />
</ItemGroup>
Vous pouvez ajouter cette section à chaque fichier projet manuellement si vous préférez ne pas utiliser l’interface CLI .NET.
Structurer une solution
Un autre aspect important des solutions à projets multiples est la mise en place d’une bonne structure de projet globale. Vous pouvez organiser le code comme vous le souhaitez, et tant que vous liez chaque projet à votre fichier solution avec , vous pouvez exécuter et au niveau de la solution.