Partage via


Utiliser ASP.NET API Core dans une bibliothèque de classes

Par Scott Addie

Ce document fournit des conseils sur l’utilisation d’API ASP.NET Core dans une bibliothèque de classes. Pour tous les autres conseils sur les bibliothèques, consultez le Guide sur les bibliothèques open source.

Déterminer les versions ASP.NET Core à prendre en charge

ASP.NET Core respecte la stratégie de prise en charge de .NET Core. Consultez la stratégie de support lors de la détermination des versions ASP.NET Core à prendre en charge dans une bibliothèque. Une bibliothèque doit :

  • Faites un effort pour prendre en charge toutes les versions ASP.NET Core classées comme Long-Term Support (LTS).
  • Ne vous sentez pas obligé de prendre en charge les versions ASP.NET Core classées comme fin de vie (EOL).

À mesure que les préversions de ASP.NET Core deviennent disponibles, des changements cassants sont publiés dans le dépôt GitHub aspnet/Announcements. Les tests de compatibilité des bibliothèques peuvent être effectués au fur et à mesure que les fonctionnalités de l’infrastructure sont développées.

Utiliser l’infrastructure partagée ASP.NET Core

Avec la version de .NET Core 3.0, de nombreux assemblys ASP.NET Core ne sont plus publiés sur NuGet en tant que packages. Au lieu de cela, les assemblys sont inclus dans l’infrastructure partagée Microsoft.AspNetCore.App, qui est installée avec le Kit de développement logiciel (SDK) .NET Core et les programmes d’installation du runtime. Pour obtenir la liste des packages qui ne sont plus publiés, consultez Supprimer les références de package obsolètes.

À partir de .NET Core 3.0, les projets utilisant le sdk MSBuild Microsoft.NET.Sdk.Web référencent implicitement l’infrastructure partagée. Les projets utilisant le sdk Microsoft.NET.Sdk ou Microsoft.NET.Sdk.Razor doivent référencer ASP.NET Core pour utiliser des API ASP.NET Core dans l’infrastructure partagée.

Pour référencer ASP.NET Core, ajoutez l’élément <FrameworkReference> suivant à votre fichier projet :

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

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

</Project>

Inclure l’extensibilité Blazor

Blazor prend en charge la création de bibliothèques de classes pour les composants Razor, destinées aux applications côté serveur et côté client. Pour prendre en charge les composants Razor d’une bibliothèque de classes, la bibliothèque de classes doit utiliser Microsoft.NET.Sdk SDKRazor.

Prendre en charge les applications côté serveur et côté client

Pour prendre en charge la consommation des composants Razor par les applications côté serveur et côté client à partir d’une seule bibliothèque, suivez les instructions suivantes pour votre éditeur.

Utilisez le modèle de projet Razor Class Library.

Remarque

Ne cochez pas la case Prise en charge des pages et des vues. La case à cocher génère une bibliothèque de classes qui prend uniquement en charge les applications côté serveur.

Bibliothèque générée à partir du modèle de projet :

  • Cible le .NET Framework actuel basé sur le Kit de développement logiciel (SDK) installé.
  • Active les vérifications de compatibilité du navigateur pour les dépendances de plateforme en incluant browser en tant que plateforme prise en charge avec l’élément MSBuild SupportedPlatform.
  • Ajoute une référence de package NuGet pour Microsoft.AspNetCore.Components.Web.

RazorClassLibrary-CSharp.csproj (source de référence)

Remarque

Les liens de documentation vers la source de référence .NET chargent généralement la branche par défaut du dépôt, qui représente le développement actuel pour la prochaine version de .NET. Pour sélectionner une balise pour une version spécifique, utilisez la liste déroulante Échanger les branches ou les balises. Pour plus d’informations, consultez Comment sélectionner une balise de version de code source ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Prise en charge de plusieurs versions de framework

Si la bibliothèque doit prendre en charge les fonctionnalités ajoutées à Blazor dans la version actuelle, tout en prenant également en charge une ou plusieurs versions antérieures, multi-ciblez la bibliothèque. Fournissez une liste séparée par des points-virgules des monikers de framework cible (TFM) dans la propriété MSBuild TargetFrameworks :

<TargetFrameworks>{TARGET FRAMEWORKS}</TargetFrameworks>

Dans l’exemple précédent, l’espace réservé {TARGET FRAMEWORKS} représente la liste de TFMs séparée par des points-virgules. Par exemple, netcoreapp3.1;net5.0.

Ne prendre en charge que la consommation côté serveur

Les bibliothèques de classes sont rarement conçues pour prendre uniquement en charge les applications côté serveur. Si la bibliothèque de classes nécessite uniquement des fonctionnalités spécifiques côté serveur, telles que l’accès à CircuitHandler ou Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage, ou utilise des fonctionnalités spécifiques à ASP.NET Core, telles que les intergiciels, les contrôleurs MVC ou Razor Pages, utilisez une des approches suivantes :

  • Spécifiez que la bibliothèque prend en charge les pages et les affichages lorsque la bibliothèque est créée avec la case à cocher Prendre en charge les pages et les affichages (Visual Studio) ou l’option -s|--support-pages-and-views avec la commande dotnet new :

    dotnet new razorclasslib -s
    
  • Fournissez uniquement une référence d’infrastructure à ASP.NET Core dans le fichier projet de la bibliothèque en plus des autres propriétés MSBuild requises :

    <ItemGroup>
      <FrameworkReference Include="Microsoft.AspNetCore.App" />
    </ItemGroup>
    

Pour plus d’informations sur les bibliothèques contenant des composants Razor, consultez Consommer des composants ASP.NET Core Razor à partir d’une bibliothèque de classes Razor (RCL).

Inclure l’extensibilité MVC

Cette section décrit les recommandations pour les bibliothèques qui incluent :

Cette section ne traite pas du multi-ciblage pour prendre en charge plusieurs versions de MVC. Pour obtenir des conseils sur la prise en charge de plusieurs versions ASP.NET Core, consultez Prendre en charge plusieurs versions ASP.NET Core.

Vues Razor ou pages Razor

Un projet qui inclut des vues Razor ou des pages Razor doit utiliser le Microsoft.NET.Sdk.Razor SDK.

Si le projet cible .NET Core 3.x, il nécessite :

  • Une propriété MSBuild AddRazorSupportForMvc définie sur true.
  • Élément <FrameworkReference> pour l’infrastructure partagée.

Le modèle de projet Razor bibliothèque de classes répond aux exigences précédentes pour les projets ciblant .NET Core. Utilisez les instructions suivantes pour votre éditeur.

Utilisez le modèle de projet Razor Class Library. La case Prendre en charge les pages et vues du modèle doit être cochée.

Par exemple:

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

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
  </PropertyGroup>

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

</Project>

Si le projet cible .NET Standard à la place, une référence de package Microsoft.AspNetCore.Mvc est requise. Le package Microsoft.AspNetCore.Mvc déplacé dans l’infrastructure partagée dans ASP.NET Core 3.0 et n’est donc plus publié. Par exemple:

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

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
  </ItemGroup>

</Project>

Tag Helpers

Un projet qui inclut Tag Helpers doit utiliser le Kit de développement logiciel (SDK) Microsoft.NET.Sdk. Si vous ciblez .NET Core 3.x, ajoutez un élément <FrameworkReference> pour le framework partagé. Par exemple:

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

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

</Project>

Si vous ciblez .NET Standard (pour prendre en charge les versions antérieures à ASP.NET Core 3.x), ajoutez une référence de package à Microsoft.AspNetCore.Mvc.Razor. Le package Microsoft.AspNetCore.Mvc.Razor déplacé dans l’infrastructure partagée et n’est donc plus publié. Par exemple:

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

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
  </ItemGroup>

</Project>

Afficher les composants

Un projet qui inclut des composants View doit utiliser le Kit de développement logiciel (SDK) Microsoft.NET.Sdk. Si vous ciblez .NET Core 3.x, ajoutez un élément <FrameworkReference> pour le framework partagé. Par exemple:

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

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

</Project>

Si vous ciblez .NET Standard (pour prendre en charge les versions antérieures à ASP.NET Core 3.x), ajoutez une référence de package à Microsoft.AspNetCore.Mvc.ViewFeatures. Le package Microsoft.AspNetCore.Mvc.ViewFeatures déplacé dans l’infrastructure partagée et n’est donc plus publié. Par exemple:

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

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Mvc.ViewFeatures" Version="2.2.0" />
  </ItemGroup>

</Project>

Prise en charge de plusieurs versions ASP.NET Core

Le ciblage multiple est nécessaire pour créer une bibliothèque qui prend en charge plusieurs variantes de ASP.NET Core. Considérez un scénario dans lequel une bibliothèque Tag Helpers doit prendre en charge les variantes principales ASP.NET suivantes :

  • ASP.NET Core 2.1 ciblant .NET Framework 4.6.1
  • ASP.NET Core 2.x ciblant .NET Core 2.x
  • ASP.NET Core 3.x ciblant .NET Core 3.x

Le fichier projet suivant prend en charge ces variantes via la propriété TargetFrameworks :

<Project Sdk="Microsoft.NET.Sdk">
  
  <PropertyGroup>
    <TargetFrameworks>netcoreapp2.1;netcoreapp3.1;net461</TargetFrameworks>
  </PropertyGroup>
  
  <ItemGroup>
    <PackageReference Include="Markdig" Version="0.16.0" />
  </ItemGroup>
  
  <ItemGroup Condition="'$(TargetFramework)' != 'netcoreapp3.1'">
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor" Version="2.1.0" />
  </ItemGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>
</Project>

Avec le fichier projet précédent :

  • Le package Markdig est ajouté pour tous les consommateurs.
  • Une référence à Microsoft.AspNetCore.Mvc.Razor est ajoutée pour les consommateurs ciblant .NET Framework 4.6.1 ou version ultérieure ou .NET Core 2.x. La version 2.1.0 du package fonctionne avec ASP.NET Core 2.2 en raison de la compatibilité descendante.
  • L'infrastructure partagée est utilisée comme référence pour les utilisateurs qui visent le framework .NET Core 3.x. Le package Microsoft.AspNetCore.Mvc.Razor est inclus dans l’infrastructure partagée.

Vous pouvez également cibler .NET Standard 2.0 au lieu de cibler .NET Core 2.1 et .NET Framework 4.6.1 :

<Project Sdk="Microsoft.NET.Sdk">
  
  <PropertyGroup>
    <TargetFrameworks>netstandard2.0;netcoreapp3.1</TargetFrameworks>
  </PropertyGroup>
  
  <ItemGroup>
    <PackageReference Include="Markdig" Version="0.16.0" />
  </ItemGroup>
  
  <ItemGroup Condition="'$(TargetFramework)' != 'netcoreapp3.1'">
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor" Version="2.1.0" />
  </ItemGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>
</Project>

Avec le fichier projet précédent, les avertissements suivants existent :

  • Étant donné que la bibliothèque contient uniquement des Tag Helpers, il est plus simple de cibler les plateformes spécifiques sur lesquelles ASP.NET Core s’exécute : .NET Core et .NET Framework. Les Tag Helpers ne peuvent pas être utilisés par d’autres frameworks cibles conformes à .NET Standard 2.0, tels que Unity et UWP.
  • L’utilisation de .NET Standard 2.0 à partir de .NET Framework présente certains problèmes qui ont été résolus dans .NET Framework 4.7.2. Vous pouvez améliorer l’expérience des consommateurs à l’aide de .NET Framework 4.6.1 à 4.7.1 en ciblant .NET Framework 4.6.1.

Si votre bibliothèque doit appeler des API spécifiques à la plateforme, ciblez des implémentations .NET spécifiques au lieu de .NET Standard. Pour plus d’informations, consultez Multiciblage.

Utiliser une API qui n’a pas changé

Imaginez un scénario dans lequel vous mettez à niveau une bibliothèque d’intergiciels de .NET Core 2.2 à 3.1. Les API de middleware ASP.NET Core utilisées dans la bibliothèque n’ont pas changé entre ASP.NET Core 2.2 et 3.1. Pour continuer à prendre en charge la bibliothèque d’intergiciels dans .NET Core 3.1, procédez comme suit :

  • Suivez les instructions de la bibliothèque standard .
  • Ajoutez une référence de package pour le package NuGet de chaque API si l’assembly correspondant n’existe pas dans l’infrastructure partagée.

Utiliser une API qui a changé

Imaginez un scénario dans lequel vous mettez à niveau une bibliothèque de .NET Core 2.2 vers .NET Core 3.1. Une API ASP.NET Core utilisée dans la bibliothèque présente un changement cassant dans ASP.NET Core 3.1. Déterminez si la bibliothèque peut être réécrite pour ne pas utiliser l’API rompue dans toutes les versions.

Si vous pouvez réécrire la bibliothèque, procédez ainsi et continuez à cibler un framework cible antérieur (par exemple, .NET Standard 2.0 ou .NET Framework 4.6.1) avec des références de package.

Si vous ne pouvez pas réécrire la bibliothèque, procédez comme suit :

  • Ajoutez une cible pour .NET Core 3.1.
  • Ajoutez un élément <FrameworkReference> pour l’infrastructure partagée.
  • Utilisez la directive de préprocesseur #if avec le symbole d’infrastructure cible approprié pour compiler le code de manière conditionnelle.

Par exemple, les lectures et écritures synchrones sur les flux de requête et de réponse HTTP sont désactivées par défaut à partir de ASP.NET Core 3.1. ASP.NET Core 2.2 prend en charge le comportement synchrone par défaut. Considérez une bibliothèque d’intergiciels dans laquelle les lectures et les écritures synchrones doivent être activées où les E/S se produisent. La bibliothèque doit placer le code pour activer les fonctionnalités synchrones dans la directive de préprocesseur appropriée. Par exemple:

public async Task Invoke(HttpContext httpContext)
{
    if (httpContext.Request.Path.StartsWithSegments(_path, StringComparison.Ordinal))
    {
        httpContext.Response.StatusCode = (int) HttpStatusCode.OK;
        httpContext.Response.ContentType = "application/json";
        httpContext.Response.ContentLength = _bufferSize;

#if !NETCOREAPP3_1 && !NETCOREAPP5_0
        var syncIOFeature = httpContext.Features.Get<IHttpBodyControlFeature>();
        if (syncIOFeature != null)
        {
            syncIOFeature.AllowSynchronousIO = true;
        }

        using (var sw = new StreamWriter(
            httpContext.Response.Body, _encoding, bufferSize: _bufferSize))
        {
            _json.Serialize(sw, new JsonMessage { message = "Hello, World!" });
        }
#else
        await JsonSerializer.SerializeAsync<JsonMessage>(
            httpContext.Response.Body, new JsonMessage { message = "Hello, World!" });
#endif
        return;
    }

    await _next(httpContext);
}

Utiliser une API introduite dans la version 3.1

Imaginez que vous souhaitez utiliser une API ASP.NET Core qui a été introduite dans ASP.NET Core 3.1. Tenez compte des questions suivantes :

  1. La bibliothèque nécessite-t-elle fonctionnellement la nouvelle API ?
  2. La bibliothèque peut-elle implémenter cette fonctionnalité de manière différente ?

Si la bibliothèque requiert fonctionnellement l’API et qu’il n’existe aucun moyen de l’implémenter à un niveau inférieur :

  • Ciblez .NET Core 3.x uniquement.
  • Ajoutez un élément <FrameworkReference> pour l’infrastructure partagée.

Si la bibliothèque peut implémenter la fonctionnalité de manière différente :

  • Ajoutez .NET Core 3.x en tant que framework cible.
  • Ajoutez un élément <FrameworkReference> pour l’infrastructure partagée.
  • Utilisez la directive de préprocesseur #if avec le symbole d’infrastructure cible approprié pour compiler le code de manière conditionnelle.

Par exemple, tag Helper suivant utilise l’interface IWebHostEnvironment introduite dans ASP.NET Core 3.1. Les consommateurs ciblant .NET Core 3.1 exécutent le chemin du code défini par le symbole de l’infrastructure cible NETCOREAPP3_1. Le type de paramètre de constructeur de Tag Helper change en IHostingEnvironment pour les utilisateurs de .NET Core 2.1 et .NET Framework 4.6.1. Cette modification a été nécessaire, car ASP.NET Core 3.1 a marqué IHostingEnvironment comme obsolète et recommandé IWebHostEnvironment comme remplacement.

[HtmlTargetElement("script", Attributes = "asp-inline")]
public class ScriptInliningTagHelper : TagHelper
{
    private readonly IFileProvider _wwwroot;

#if NETCOREAPP3_1
    public ScriptInliningTagHelper(IWebHostEnvironment env)
#else
    public ScriptInliningTagHelper(IHostingEnvironment env)
#endif
    {
        _wwwroot = env.WebRootFileProvider;
    }

    // code omitted for brevity
}

Le fichier projet multi-ciblé suivant prend en charge ce scénario Tag Helper :

<Project Sdk="Microsoft.NET.Sdk">
  
  <PropertyGroup>
    <TargetFrameworks>netcoreapp2.1;netcoreapp3.1;net461</TargetFrameworks>
  </PropertyGroup>
  
  <ItemGroup>
    <PackageReference Include="Markdig" Version="0.16.0" />
  </ItemGroup>
  
  <ItemGroup Condition="'$(TargetFramework)' != 'netcoreapp3.1'">
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor" Version="2.1.0" />
  </ItemGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>
</Project>

Utiliser une API supprimée de l’infrastructure partagée

Pour utiliser un assembly ASP.NET Core qui a été supprimé de l’infrastructure partagée, ajoutez la référence de package appropriée. Pour obtenir la liste des packages supprimés de l’infrastructure partagée dans ASP.NET Core 3.1, consultez Supprimer les références de package obsolètes.

Par exemple, pour ajouter le client d’API web :

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

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
  </ItemGroup>

</Project>

Ressources additionnelles