ASP.NET Core でのアプリケーションのスタートアップ

Note

これは、この記事の最新バージョンではありません。 現在のリリースについては、 この記事の .NET 10 バージョンを参照してください。

Warning

このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、 .NET および .NET Core サポート ポリシーを参照してください。 現在のリリースについては、 この記事の .NET 10 バージョンを参照してください。

この記事では、アプリ ASP.NET Core起動する方法と、サービスとアプリの要求パイプラインを構成する方法について説明します。

この記事のガイダンスに追加されるまたは優先する Blazor 起動のガイダンスについては、「ASP.NET Core Blazor の起動」をご覧ください。

Program ファイル

ASP.NET Coreアプリは、アプリのProgram ファイル (Program.cs) でスタートアップを初期化して構成します。

Program ファイルの最初の部分では、アプリのビルドに重点を置いています。 このフェーズでは、 WebApplication.CreateBuilder を使用して、アプリを開始する前に、事前構成済みの既定値を使用して WebApplicationBuilder クラスの新しいインスタンスを初期化します。 ASP.NET Core プロジェクト テンプレートは、web アプリケーション ビルダーを builder という名前の変数に割り当てます。

var builder = WebApplication.CreateBuilder(args);

Web アプリケーション ビルダーのプロパティは次のとおりです。

アプリは、ビルドされたWebApplicationを返すWebApplicationBuilder.Buildを呼び出すことによってビルドされます。 ASP.NET Core プロジェクト テンプレートは、ビルドされた Web アプリケーションを app という名前の変数に割り当てます。

var app = builder.Build();

Program ファイルの次の部分では、一連のミドルウェア コンポーネントとして HTTP 要求処理パイプラインを確立することに重点を置いています。 各ミドルウェアは、 HttpContext に対して操作を実行し、パイプライン内の次のミドルウェアを呼び出すか、要求を終了します。 慣例により、ミドルウェア コンポーネントは、"Use" で始まる拡張メソッドを呼び出すことによってパイプラインに追加されます。詳細については、ミドルウェア ASP.NET Core参照してください。

Run メソッドは、アプリを起動し、ホストがシャットダウンされるまで呼び出し元のスレッドをブロックします。

app.Run();

Run実行すると、アプリはアクティブで実行中のプロセスに移行します。

  1. ホステッド サービスが開始されます。

    ホストは、登録されているすべての ホステッド サービス (IHostedService インスタンス) をループし、 StartAsync メソッドを呼び出します。 アプリが同時ホステッド サービスの起動 (.NET 8 以降) を選択しない限り、ホストされるサービスは DI コンテナーの登録の順序で順番に開始されます。 詳細については、「ASP.NET Coreでホストされているサービスを使用したバックグラウンド タスク」を参照してください。

  2. ミドルウェア パイプラインが構築されています。

    builder.Buildが呼び出されると、依存関係は解決されますが、実際の処理パイプラインは完全には設定されません。 app.Run実行すると、フレームワークは HTTP ミドルウェア パイプラインを最終処理します。 宣言されたミドルウェア メソッドとエンドポイント マッピングは、1 つの高パフォーマンス実行デリゲート シーケンスにコンパイルされます。 詳細については、ミドルウェア ASP.NET Core参照してください。

  3. Web サーバー (既定ではKestrel ) が開始されます。

    ホストは依存関係コンテナー内を検索し、登録済みのサーバー実装 (通常は Kestrel) を見つけ、その起動サイクルをトリガーします。 Kestrel 次に、次の手順を実行

    • 構成、環境変数、またはコマンド ライン引数から、定義されたホスティング URL とポートを検索します。
    • 物理ネットワーク ソケットを開いて割り当てます。
    • ポートをバインドし、受信トラフィックの待ち受けを開始します。

    詳細については、「ASP.NET Core の汎用ホスト.NET、ASP.NET Coreでの Web サーバーの実装、および ASP.NET Core の Web サーバーのKestrel」を参照してください。

  4. アプリケーションの起動時のライフタイム イベントがトリガーされます。

    IHostApplicationLifetime サービスはそのApplicationStarted トークンを起動し、トークンに登録されているコールバックを呼び出します。 トークンが発火するのを待つように設定されているコールバック、データベースシーダー、その他のカスタムイベントリスナーが起動され、処理を開始します。

  5. メイン実行スレッドは、アプリの実行中にブロックされます。

    Run (app.Run()) シャットダウンまで同期的に待機します。

  6. アプリは要求を処理する準備ができています。

    この時点で、コマンド シェルは診断をホストするログを記録します。

    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.
    

アプリは無期限にこの状態のままであり、受信 Web トラフィックをミドルウェア パイプラインに渡し、応答を送信します。

シャットダウンが通知された場合 (たとえば、アプリを実行しているコマンド シェルで Ctrl+c が検出された場合、またはコンテナー オーケストレーション ツールが SIGTERM イベントを送信すると、 Run ブロックが解除され、次のアクションが実行されます。

  1. ApplicationStopping トークンがトリガーされます。これにより、シャットダウン プロセスが開始される前にアプリでロジックを実行できます。

  2. Kestrel サーバーがシャットダウンされ、新しい接続が無効になります。 サーバーは、シャットダウン タイムアウトが許す限り、既存の接続の要求が完了するまで待機します。 サーバーは、既存の接続でのその後の要求に対し、接続終了ヘッダーを送信します。

  3. ホストは、登録済みのホステッド サービスをシャットダウンします。 アプリがホストされたサービスを同時に停止することを選択しない限り (.NET 8 以降)、ホストされるサービスは DI コンテナー登録の逆の順序で順番に停止します。 詳細については、「ASP.NET Coreでホストされているサービスを使用したバックグラウンド タスク」を参照してください。

  4. ApplicationStopped イベント ハンドラーがトリガーされます。これにより、アプリのシャットダウン後にアプリでロジックを実行できます。

  5. コンソールの実行は、終了コード 0 で正常に終了します。

Startup クラスはサービスとアプリケーションの要求パイプラインを構成します。

Startup クラス

ASP.NET Coreアプリでは、慣例によりStartupという名前のスタートアップ クラスが使用されます。 Startup クラス:

  • オプションで ConfigureServices メソッドを含め、アプリケーションのサービスを構成することができます。 サービスとは、アプリ機能を提供する再利用可能なコンポーネントです。 サービスは にConfigureServicesで登録され、依存性注入 (DI) または ApplicationServices を使ってアプリ全体で利用されます。
  • アプリの要求処理パイプラインを作成するために Configure メソッドを含めます。

ConfigureServices と Configure はアプリの起動時に ASP.NET Core ランタイムによって呼び出されます。

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

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

アプリのStartupがビルドされるときに、クラスが指定されます。 Startup クラスは、通常、ホスト ビルダーでWebHostBuilderExtensions.UseStartupを呼び出すことによって指定されます。

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>();
            });
}

ホストには、Startup クラス コンストラクターで使用できるサービスが用意されています。 アプリケーションから ConfigureServices 経由でサービスが追加されます。 ホスト サービスとアプリ サービスの両方が Configure 内とアプリ全体で使用できます。

Startup () を使用すると、次のサービスの種類のみを 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
        {
        }
    }
}

ほとんどのサービスは、 Configure メソッドが呼び出されるまで使用できません。

Note

前の例の IWebHostEnvironment のプライベート フィールドの名前はアンダースコア (_env) です。 プライベート フィールドが this キーワード (コンストラクターでthis.env = env、ConfigureServices メソッドでenv.IsDevelopment()) を使用する場合は、挿入されたIWebHostEnvironment (env) と同じ名前を使用するコーディング規則を採用することもできます。

.NET 8 および C# 12 より前の ASP.NET Core プロジェクト テンプレートはプライマリ コンストラクターを採用していませんが、組織が .NET 8 以降の SDK を使用していて、アプリが C# 12 以降をターゲットとする場合 (たとえば、<LangVersion>12.0</LangVersion>) 場合は、上記のコードをリファクタリングしてプライマリ コンストラクターを採用できます。 詳細については、クラスと構造体のプライマリ コンストラクターの宣言 (C# ドキュメント チュートリアル) とプライマリ コンストラクター (C# ガイド) を参照してください。

複数の Startup クラス

アプリケーションの環境 (たとえば Startup) ごとに個別の StartupDevelopment クラスが定義されると、実行時に適切な Startup クラスが選択されます。 名前のサフィックスが現在の環境と一致するクラスが優先されます。 アプリが Development 環境で実行され、 Startup クラスと StartupDevelopment クラスの両方が含まれている場合は、 StartupDevelopment クラスが使用されます。 詳細については、「Use multiple environments」(複数の環境の使用) を参照してください。

ConfigureServices メソッド

省略可能な ConfigureServices メソッドは次のとおりです。

  • アプリケーションのサービスを構成する Configure メソッドの前にホストによって呼び出されます。
  • 規約によって構成オプションが設定されます。

ホストでは、Startup メソッドが呼び出される前にいくつかのサービスを構成することができます。 詳細については、「 ASP.NET コアの基礎の概要」を参照してください。

大幅なセットアップを必要とする機能の場合、IServiceCollectionには次のようなAdd{Service}拡張メソッドがあります。

  • 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();
    }
}

サービス コンテナーにサービスを追加すると、アプリケーション内と Configure メソッド内でサービスを利用できるようになります。 サービスは依存関係の挿入または ApplicationServices によって解決されます。

Configure メソッド

Configure メソッドは、アプリケーションが HTTP 要求にどのように応答するかを指定するために使用されます。 要求パイプラインは、ミドルウェア コンポーネントを IApplicationBuilder インスタンスに追加することで構成されます。 IApplicationBuilder は Configure メソッドから使用できますが、サービス コンテナーに登録されていません。 ホスティングによって IApplicationBuilder が作成され、Configure に直接渡されます。

ASP.NET Core テンプレートでは、次をサポートするパイプラインが構成されます。

次の例は、一般的な Razor Pages アプリのミドルウェアを示しています。

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();
        });
    }
}

上記のサンプルは Razor Pages 用です。MVC バージョンは似ています。

各 Use 拡張メソッドによって、要求パイプラインに 1 つまたは複数のミドルウェア コンポーネントが追加されます。 たとえば、UseStaticFiles は ミドルウェア を構成して、静的ファイルを提供します。

要求パイプライン内の各ミドルウェア コンポーネントは、パイプラインの次のコンポーネントを呼び出すか、妥当な場合はチェーンをショートさせます。

IWebHostEnvironment、ILoggerFactory、または ConfigureServices で定義された任意のものなどの追加サービスを Configure メソッド シグネチャで指定できます。 使用可能な場合、これらのサービスが挿入されます。

IApplicationBuilderの使用方法とミドルウェア処理の順序の詳細については、ミドルウェアの ASP.NET Coreを参照してください。

Startup クラスを使用せずにサービスを構成する

Startup クラスを使用せず、サービスと要求処理パイプラインを構成するには、ホスト ビルダーで便利なメソッド、ConfigureServices と Configure を呼び出します。 ConfigureServices の複数回の呼び出しでは、互いに追加されます。 Configure メソッドが複数回呼び出された場合、最後の Configure 呼び出しが使用されます。

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 =>
                {
                    ...
                });
        });
}

スタートアップ フィルター

アプリは通常、明示的なミドルウェア実行パイプラインを作成しますが、スタートアップ フィルター (IStartupFilter) は次の場合に役立ちます。

  • アプリがミドルウェアの "Use" メソッドを明示的に呼び出す必要なく、カスタム ミドルウェアを自動的に読み込む共有ライブラリ/NuGet パッケージを作成する。 たとえば、ライブラリのコンシューマーは、アプリの要求処理パイプラインで画像処理ミドルウェアの app.UseImageProcessingMiddleware 呼び出しを行う必要はありません。
  • 開発者がアプリの要求処理パイプラインを変更する方法に関係なく、ミドルウェアの一部が他のミドルウェアの前または後に実行されることを保証します。

スタートアップ フィルターの実装は、Action<IApplicationBuilder>を受け取って返すIStartupFilter.Configure メソッドを提供します。 IApplicationBuilder インターフェイスは、アプリの要求パイプラインを構成するために使用されます。 詳細については、「IApplicationBuilderを使用してミドルウェア パイプラインを作成する」を参照してください。

各スタートアップ フィルター実装では、要求パイプラインに 1 つ以上のミドルウェアを追加できます。 フィルターは、サービス コンテナーに追加された順序で呼び出されます。 フィルターは、次のフィルターに制御を渡す前または後にミドルウェアを追加できるため、パイプラインの先頭または末尾に追加されます。

IStartupFilter でミドルウェアを登録する方法を次の例に示します。 CustomResponseHeaderFilterスタートアップ フィルターでは、ミドルウェアを使用して、他のミドルウェアを実行する前に、カスタム ヘッダー (X-Custom-Header) をアプリのすべての応答に追加します。

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
        };
    }
}

スタートアップ フィルターの実装は、 Program ファイルに登録されます。

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

スタートアップ フィルターの実装は、 Startup.ConfigureServicesに登録されます。

services.AddTransient<IStartupFilter, CustomResponseHeaderFilter>();

ミドルウェアの実行順序は、スタートアップ フィルター登録の順序によって設定されます。

  • 複数の実装が同じオブジェクトと対話する場合があります。 順序付けが重要な場合は、ミドルウェアの実行順序に合わせてサービス登録を並べ替える必要があります。
  • ライブラリは、 IStartupFilterに登録された他のアプリ ミドルウェアの前または後に実行される 1 つ以上の実装を含むミドルウェアを追加できます。 ライブラリのスタートアップ フィルターによって追加されたミドルウェアの前にスタートアップ フィルター ミドルウェアを呼び出すには:
    • ライブラリがサービス コンテナーに追加される前に、スタートアップ フィルター サービスの登録を配置します。
    • 後で呼び出すために、ライブラリが追加された後にサービス登録を配置する

Note

Configure デリゲートをオーバーライドする場合、スタートアップ フィルターを使用して ASP.NET Core アプリを拡張することはできません。 詳細については、「 WebApplicationFactory Client returns NotFound for all requests with Overriding Configure method (dotnet/aspnetcore #45372)」を参照してください。

外部アセンブリからの起動時に構成を追加する

IHostingStartup実装では、アプリのProgram ファイルまたはStartup クラスの外部アセンブリから起動時にアプリに拡張機能を追加できます。 詳細については、「ASP.NET Core でホスティング スタートアップ アセンブリを使用する」を参照してください。

Startup クラス (ConfigureServices メソッドとConfigure メソッド)

.NET 6 以降をターゲットとする ASP.NET Core アプリではサポートされていますが、Startup クラスの使用はお勧めしません。 詳細については、「 .NET 5 の ASP.NET Core から .NET 6 への移行」を参照してください。

最小限のホスティング モデルで ConfigureServices メソッドと Configure メソッドを使用する方法については、次を参照してください。

スタートアップ パフォーマンスを測定する

ASP.NET Core ホスティング EventSourceは、ServerReady イベントを生成します。これは、サーバーが要求に応答する準備が整い、起動時間を測定するために使用できるポイントを表します。 詳細については、「 .NET および ASP.NET Core でのログ記録」を参照してください。