Démarrage d’une application dans ASP.NET Core

Note

Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version .NET 10 de cet article.

Warning

Cette version d’ASP.NET Core n’est plus prise en charge. Pour plus d’informations, consultez la stratégie de support .NET et .NET Core. Pour la version actuelle, consultez la version .NET 10 de cet article.

Cet article explique comment ASP.NET Core applications démarrent et comment configurer des services et le pipeline de requête de l'application.

Pour obtenir des instructions sur le démarrage de Blazor, en complément ou en remplacement des instructions de cet article, consultez Démarrage de Blazor ASP.NET Core.

Le fichier Program

ASP.NET Core applications initialisent et configurent le démarrage dans le fichier de Program l'application (Program.cs).

La première partie du Program fichier se concentre sur la création de l’application. Cette phase utilise WebApplication.CreateBuilder pour initialiser une nouvelle instance de la WebApplicationBuilder classe avec des valeurs par défaut préconfigurées avant le démarrage de l’application. Les modèles de projet ASP.NET Core attribuent au générateur d’applications web une variable nommée builder:

var builder = WebApplication.CreateBuilder(args);

Les propriétés du générateur d’applications web sont les suivantes :

L’application est générée en appelant WebApplicationBuilder.Build, qui retourne le fichier généré WebApplication. Les modèles de projet ASP.NET Core attribuent l’application web générée à une variable nommée app:

var app = builder.Build();

La partie suivante du Program fichier se concentre sur l’établissement du pipeline de gestion des requêtes HTTP en tant que série de composants middleware. Chaque middleware effectue des opérations sur un HttpContext et invoque le middleware suivant dans le pipeline de traitement, ou met fin à la requête. Par convention, les composants middleware sont ajoutés au pipeline en appelant une méthode d’extension qui commence par «Use ». Pour plus d’informations, consultez ASP.NET Core intergiciel.

La méthode Run démarre l’application et bloque le thread appelant jusqu’à ce que l’hôte soit arrêté :

app.Run();

Lorsque Run s’exécute, l’application passe à l’état de processus actif :

  1. Les services hébergés démarrent.

    L’hôte effectue une boucle via tous les services hébergés inscrits (IHostedService instances) et appelle leurs StartAsync méthodes. À moins que l’application n’opte pour le démarrage simultané du service hébergé (.NET 8 ou version ultérieure), les services hébergés démarrent de façon séquentielle dans l’ordre de leurs inscriptions de conteneurs d’di. Pour plus d’informations, consultez Tâches en arrière-plan avec des services hébergés dans ASP.NET Core.

  2. Le pipeline de middleware est construit.

    Lorsque builder.Build est appelé, les dépendances sont résolues, mais le pipeline de traitement proprement dit n’est pas encore entièrement défini. Lorsque app.Run s’exécute, le framework finalise le pipeline de middleware HTTP. Les méthodes d’intergiciel déclarées et les mappages de points de terminaison sont compilés en une séquence de délégués d’exécution haute performance unique. Pour plus d’informations, consultez ASP.NET Core intergiciel.

  3. Le serveur web (Kestrel par défaut) est démarré.

    L’hôte consulte son conteneur d’injection de dépendances, y localise l’implémentation de serveur enregistrée (généralement Kestrel) et lance sa séquence de démarrage. Kestrel puis :

    • Recherche les URL et ports d’hébergement définis à partir de la configuration, des variables d’environnement ou des arguments de ligne de commande.
    • Ouvre et alloue des sockets réseau physiques.
    • Lie les ports et commence à écouter le trafic entrant.

    Pour plus d’informations, consultez .NET Hôte générique dans ASP.NET Core, implémentations de serveur web dans ASP.NET Core et Kestrel serveur web dans ASP.NET Core.

  4. Les événements du cycle de vie sont déclenchés au démarrage de l’application.

    Le service IHostApplicationLifetime déclenche son jeton ApplicationStarted, qui appelle les rappels inscrits sur le jeton. Toutes les fonctions de rappel, les scripts d’initialisation de la base de données ou les autres écouteurs d’événements personnalisés configurés pour attendre le déclenchement du jeton sont activés pour lancer le traitement.

  5. Le thread d’exécution principal est bloqué pendant l’exécution de l’application.

    Run (app.Run()) attend de façon synchrone jusqu’à l’arrêt.

  6. L’application est prête à traiter les demandes.

    À ce stade, l’interpréteur de commandes consigne les diagnostics d’hébergement :

    info: Microsoft.Hosting.Lifetime[14]
          Now listening on: https://localhost:7123
    info: Microsoft.Hosting.Lifetime[14]
          Now listening on: http://localhost:5123
    info: Microsoft.Hosting.Lifetime[0]
          Application started. Press Ctrl+C to shut down.
    

L’application reste dans cet état indéfiniment, transmettant le trafic web entrant au pipeline de middleware et renvoyant des réponses.

Lorsque l’arrêt est signalé, par exemple lorsque Ctrl+c est détecté dans l’interpréteur de commandes exécutant l’application ou un outil d’orchestration de conteneur envoie un événement SIGTERM, Run débloque et les actions suivantes se produisent :

  1. ApplicationStopping les jetons sont déclenchés, ce qui permet à l’application d’exécuter la logique avant le début du processus d’arrêt.

  2. Le Kestrel serveur est arrêté, ce qui désactive les nouvelles connexions. Le serveur attend que les demandes sur les connexions existantes se terminent tant que le délai d’arrêt le permet. Le serveur envoie l’en-tête de fermeture de connexion pour les requêtes supplémentaires sur les connexions existantes.

  3. L’hôte arrête les services hébergés enregistrés. Sauf si l’application choisit d’arrêter les services hébergés simultanément (.NET 8 ou version ultérieure), les services hébergés s’arrêtent de façon séquentielle dans l’ordre inverse de leurs inscriptions de conteneurs d’di. Pour plus d’informations, consultez Tâches en arrière-plan avec des services hébergés dans ASP.NET Core.

  4. ApplicationStopped les gestionnaires d’événements sont déclenchés, ce qui permet à l’application d’exécuter la logique après l’arrêt de l’application.

  5. L’exécution de la console se termine avec un code de sortie de 0.

La classe Startup configure les services et le pipeline de demande de l’application.

La classe Startup

ASP.NET Core applications utilisent une classe de démarrage, nommée Startup par convention. La classe Startup :

  • Inclut éventuellement une méthode ConfigureServices pour configurer les services de l’application. Un service est un composant réutilisable qui fournit une fonctionnalité d’application. Les services sont inscrits dans ConfigureServices et consommés dans l’application par injection de dépendance ou ApplicationServices.
  • Inclut une méthode Configure pour créer le pipeline de traitement des requêtes de l’application.

ConfigureServices et Configure sont appelés par le runtime ASP.NET Core au lancement de l’application :

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        ...
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        ...
    }
}

La classe Startup est spécifiée quand l’hôte de l’application est créé. La Startup classe est généralement spécifiée en appelant WebHostBuilderExtensions.UseStartup le générateur d’hôtes :

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

L’hôte fournit des services accessibles au constructeur de classe Startup. L’application ajoute des services supplémentaires à l’aide de ConfigureServices. Les services de l’hôte ainsi que ceux de l’application sont disponibles dans Configure et dans l’ensemble de l’application.

Seuls les types de service suivants peuvent être injectés dans le constructeur Startup lorsque vous utilisez l’hôte générique (IHostBuilder) :

public class Startup
{
    private readonly IWebHostEnvironment _env;

    public Startup(IConfiguration configuration, IWebHostEnvironment env)
    {
        Configuration = configuration;
        _env = env;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        if (_env.IsDevelopment())
        {
        }
        else
        {
        }
    }
}

La plupart des services ne sont pas disponibles tant que la Configure méthode n’est pas appelée.

Note

Le champ privé de l’exemple IWebHostEnvironment précédent est nommé avec un trait de soulignement (_env). Il est également acceptable d’adopter une convention de codage qui utilise le même nom que l’élément injecté IWebHostEnvironment(env) lorsque le champ privé utilise le mot-clé this (this.env = env dans le constructeur et env.IsDevelopment() dans la méthode ConfigureServices).

Les modèles de projet ASP.NET Core avant .NET 8 et C# 12 n'adoptent pas de constructeurs principaux, mais le code précédent peut être refactorisé pour adopter un constructeur principal si votre organisation utilise un sdk .NET 8 ou ultérieur et que l'application cible C# 12 ou version ultérieure (par exemple). <LangVersion>12.0</LangVersion> Pour plus d’informations, consultez Déclarer des constructeurs principaux pour les classes et les structs (didacticiel de documentation C#) et les constructeurs principaux (Guide C#).

Plusieurs Startup classes

Quand l’application définit différentes classes Startup pour différents environnements (par exemple, StartupDevelopment), la classe Startup appropriée est sélectionnée au moment de l’exécution. La classe dont le suffixe du nom correspond à l'environnement actuel est prioritaire. Si l’application est exécutée dans l’environnement Development et inclut une classe Startup et une classe StartupDevelopment, la classe StartupDevelopment est utilisée. Pour plus d’informations, consultez Utiliser plusieurs environnements.

Méthode ConfigureServices

La méthode facultative ConfigureServices est :

  • Appelée par l’hôte avant la méthode Configure pour configurer les services de l’application
  • L’emplacement où les options de configuration sont définies par convention.

L’hôte peut configurer certains services avant l’appel des méthodes Startup. Pour plus d’informations, consultez ASP.NET vue d’ensemble des principes fondamentaux de base.

Pour les fonctionnalités nécessitant une configuration importante, il existe des méthodes d’extension Add{Service} sur IServiceCollection, telles que :

  • AddDbContext
  • AddDefaultIdentity
  • AddEntityFrameworkStores
  • AddRazorPages
public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {

        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<IdentityUser>(
            options => options.SignIn.RequireConfirmedAccount = true)
            .AddEntityFrameworkStores<ApplicationDbContext>();

        services.AddRazorPages();
    }
}

L’ajout de services au conteneur de service les rend disponibles dans l’application et dans la méthode Configure. Les services sont résolus via l’injection de dépendances ou à partir de ApplicationServices.

Méthode Configure

La méthode Configure permet de spécifier le mode de réponse de l’application aux requêtes HTTP. Vous configurez le pipeline de requête en ajoutant des composants d’intergiciel (middleware) à une instance de IApplicationBuilder. IApplicationBuilder est disponible pour la méthode Configure, mais elle n’est pas inscrite dans le conteneur de service. L’hébergement crée un IApplicationBuilder et le passe directement à Configure.

Les modèles ASP.NET Core configurent le pipeline pour permettre la prise en charge des éléments suivants :

L’exemple suivant illustre l’intergiciel pour une application Pages standard Razor :

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

L’échantillon précédent concerne les Pages Razor, toutefois, la version MVC est similaire.

Chaque méthode d’extension Use ajoute un ou plusieurs composants de middleware au pipeline de requête. Par exemple, UseStaticFiles configure le middleware pour qu’il traite des fichiers statiques.

Chaque composant de middleware du pipeline des requêtes est chargé d’appeler le composant suivant du pipeline ou de court-circuiter la chaîne, si c’est approprié.

Vous pouvez spécifier des services supplémentaires (comme IWebHostEnvironment, ILoggerFactory et tout service défini dans ConfigureServices) dans la signature de la méthode Configure. Ces services sont injectés s’ils sont disponibles.

Pour plus d’informations sur l’utilisation IApplicationBuilder et l’ordre du traitement des intergiciels, consultez ASP.NET Core middleware.

Configurer des services sans Startup classe

Pour configurer les services et le pipeline de traitement de requête sans utiliser de classe Startup, appelez les méthodes pratiques ConfigureServices et Configure sur le générateur de l’hôte. Les appels multiples à ConfigureServices s’ajoutent les uns aux autres. S’il existe plusieurs appels de méthode Configure, le dernier appel de Configure est utilisé.

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.ConfigureServices(services =>
                {
                    ...
                })
                .Configure(app =>
                {
                    ...
                });
        });
}

Filtres de démarrage

Bien qu’une application crée généralement un pipeline d’exécution d’intergiciel explicite, un filtre de démarrage (IStartupFilter) est utile pour :

  • Création d’une bibliothèque partagée/package NuGet qui charge automatiquement un intergiciel personnalisé sans exiger que l’application appelle explicitement la méthode «Use » du middleware. Par exemple, le consommateur de la bibliothèque n’est pas obligé d’effectuer un appel pour un app.UseImageProcessingMiddleware intergiciel de traitement d’images dans le pipeline de traitement des demandes de l’application.
  • Garantir qu’un intergiciel s’exécute avant ou après d’autres intergiciels, quelle que soit la manière dont un développeur modifie le pipeline de traitement des requêtes de l’application.

Une implémentation de filtre de démarrage fournit une IStartupFilter.Configure méthode qui reçoit et retourne un Action<IApplicationBuilder>. L’interface IApplicationBuilder est utilisée pour configurer le pipeline de requête de l’application. Pour plus d’informations, consultez Créer un pipeline d’intergiciel avec IApplicationBuilder.

Chaque implémentation de filtre de démarrage peut ajouter un ou plusieurs intergiciels au pipeline de requête. Les filtres sont appelés dans l’ordre dans lequel ils sont ajoutés au conteneur de service. Les filtres peuvent ajouter des middleware avant ou après avoir transmis le contrôle au filtre suivant ; ils s’ajoutent ainsi au début ou à la fin du pipeline.

L’exemple suivant montre comment inscrire un middleware auprès de IStartupFilter. Le CustomResponseHeaderFilter filtre de démarrage utilise l’intergiciel pour ajouter un en-tête personnalisé (X-Custom-Header) à toutes les réponses de l’application avant l’exécution d’autres intergiciels.

CustomResponseHeaderFilter.cs :

using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;

public class CustomResponseHeaderFilter : IStartupFilter
{
    public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
    {
        return builder =>
        {
            // 1. Add middleware that runs BEFORE subsequent middlewares
            builder.Use(async (context, nextMiddleware) =>
            {
                context.Response.Headers.Append("X-Custom-Header", "VALUE");
                await nextMiddleware();
            });

            // 2. Call the rest of the application's configuration pipeline
            next(builder);

            // 3. (Optional) Add middleware that runs AFTER the rest of the pipeline
        };
    }
}

L’implémentation du filtre de démarrage est inscrite dans le Program fichier :

builder.Services.AddTransient<IStartupFilter, CustomResponseHeaderFilter>();

L’implémentation du filtre de démarrage est inscrite dans Startup.ConfigureServices:

services.AddTransient<IStartupFilter, CustomResponseHeaderFilter>();

L’ordre d’exécution du middleware est défini par l’ordre des inscriptions de filtre de démarrage :

  • Plusieurs implémentations peuvent interagir avec les mêmes objets. Si l’ordre est important, organisez leurs enregistrements de services pour qu’ils correspondent à l’ordre dans lequel leurs middlewares doivent s’exécuter.
  • Les bibliothèques peuvent ajouter un intergiciel avec une ou plusieurs implémentations qui s’exécutent avant ou après d’autres intergiciels d’application enregistrés avec IStartupFilter. Pour appeler un intergiciel de filtre de démarrage avant l’ajout d’un middleware par le filtre de démarrage d’une bibliothèque :
    • Placez l’enregistrement du service de filtre de démarrage avant que la bibliothèque ne soit ajoutée au conteneur de services.
    • Pour les appels suivants, placez l’inscription du service après l’ajout de la bibliothèque.

Note

Vous ne pouvez pas étendre l’application ASP.NET Core avec des filtres de start-up quand vous remplacez le délégué Configure. Pour plus d’informations, consultez le client WebApplicationFactory renvoie « NotFound » pour toutes les requêtes lors de la redéfinition de la méthode Configure (dotnet/aspnetcore #45372).

Ajouter la configuration au démarrage à partir d’un assembly externe

Une implémentation de IHostingStartup permet d’ajouter des extensions à une application au démarrage depuis un assembly externe, en dehors du fichier Startup ou de la classe Program de l’application. Pour plus d’informations, consultez Utiliser des assemblys d’hébergement au démarrage dans ASP.NET Core.

La classe Startup (méthodes ConfigureServices et Configure)

Bien que pris en charge dans les applications ASP.NET Core ciblant .NET 6 ou une version ultérieure, l’utilisation d’une classe Startup n’est pas recommandée. Pour plus d’informations, consultez Migrer de ASP.NET Core dans .NET 5 vers .NET 6.

Pour plus d’informations sur l’utilisation des ConfigureServicesConfigure méthodes avec le modèle d’hébergement minimal, consultez les rubriques suivantes :

Mesurer les performances de démarrage

L’hébergement EventSource ASP.NET Core émet l’événementServerReady, qui représente le point où le serveur est prêt à répondre aux demandes et peut être utilisé pour mesurer le temps de démarrage. Pour plus d’informations, consultez Journalisation dans .NET et ASP.NET Core.