ASP.NET Core入門 – Program.cs 解説【.NET 8】

こんにちは、サイオステクノロジーの佐藤 陽です。
今回は、ASP.NET Core入門シリーズ第二弾として、Program.cs ファイルの中身について解説していきたいと思います。

  • ASP.NET Core をこれから使っていくよ!
  • Program.cs って何が書いてあるの?
  • Startup.cs どこいった?

といった方はぜひ読んでみてください。

また前回の記事から繰り返しになりますが
まだ自分も勉強中の身なので、記事の内容に誤りなどありましたらコメントにて指摘いただけると幸いです。

はじめに

今回はAPS.NET Core のプロジェクトの肝である(?)、 Program.cs のファイルをコードレベルで解説していきたいと思います。

ちなみにASP.NET Core 5時代のものに関しては、武井さんの記事でも紹介していただいてます。

多分わかりやすいASP.NET Core Webアプリケーション

ただ、こちらもなんだかんだ 5 年前の記事であり
色々と ASP.NET Core も変わってきているため、更新の意味も込めて改めて書いてみたいと思います。

ASP.NET Coreとは?

ASP.NET Core は、.NET プラットフォームをベースとするフレームワークです。

以前は、ASP.NET のフレームワークが幅広く利用されていました。
ASP.NET Core は、ASP.NET を改良したものになります。

そして ASP.NET Core も年々進化し、2024年4月現在は LTS リリースとしては ASP.NET Core 8.0 が最新のものになります。
今回の記事は ASP.NET Core 8.0 を対象としたいと思います。

ASP.NET Coreの全体像

まず初めに、 ASP.NET Core のアプリがどのように動作するかについて見ていきたいと思います。
動作を理解したうえで Program.cs の中身を見た方が理解が捗るためです。

なお前提として、今回は IIS インプロセスホスティングのケースを見ていきたいと思います。
「ホスティングについてよくわからないよー」という方は前回の記事をご覧ください。

ASP.NET Core入門 – ホスティング 解説【.NET 8】

ではまず全体の流れを図に示します。

  1. IIS Server に含まれる ASP.NET Core Module が 、dotnet コマンドにより ASP.NET Core アプリケーションを起動します。
    なおこの ASP.NET Core アプリケーションというのは単なるコンソールアプリケーションにすぎません。
    そしてこのコンソールアプリケーションのコードこそが Program.cs ファイルに含まれています
  2. コンソールアプリケーションが、 IISHTTPServer をホストし、アプリを開始します。
  3. IIS Server がリクエストを受けると IISHTTPServer へとルーティングします。
  4. リクエストは ASP.NET Core ミドルウェアパイプラインにて処理されます
  5. ミドルウェアパイプラインでの処理後、HttpContext としてアプリケーションコードに渡され、アプリケーションコードにて処理されます

といった流れとなります。

このあたりの流れは公式のドキュメントにも記載があります。

この後、実際にProgram.csのソースコードを追っていきますが
上の図や、全体の流れと照らし合わせながら見ていただくと、より理解しやすいかと思います。

プロジェクトを作成してみる

早速プロジェクトを作ってみたいと思います。

用意するもの

プロジェクト作成

以下の dotnet コマンドを利用して新規プロジェクトを作成します。

dotnet new mvc -o aspnetcore-8-mvc

実行してみる

せっかく作ったので一度実行してみます。

dotnet run --project .\aspnetcore-8-mvc\aspnetcore-8-mvc.csproj

実行が完了したら、ブラウザで

http://localhost:5088

にアクセスします。
すると、アプリにアクセスできるかと思います。

プロジェクトの中身を見てみる

また、プロジェクトの中身としては以下のようなものが作成されるかと思います。
今回はProgram.csファイルに絞って解説していきたいと思います。

Startup.cs クラスは?

ASP.NET Core 5.0 あたりまでのバージョンをメインで開発されていた方の中には

「Startup.csファイルってどこ行ったの??」

と思われる人もいるかと思います。

ここが ASP.NET Core 5.0 と 6.0 以降のバージョンで大きな違いの 1 つでもあります。

ASP.NET Core 6.0 以降では最小ホスティングモデルといったものが採用され
Startup.cs と Program.cs が 1 つの Program.cs ファイルに統合されています。

なお、統合されたといっても機能的には同一のものであり
ASP.NET Core 6.0 以降でも以前のように Startup.cs ファイルを使った記述も可能です。

「わざわざ新しい最小ホスティングモデルに切り替える必要は無い」と公式ドキュメントにも記載があります。

参考:よく寄せられる質問 (FAQ)

Program.cs の中身

先ほど作成したプロジェクトの Program.cs の中身を見てみます。

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

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

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

では早速、上から順を追って見ていきたいと思います。

Builder作成

var builder = WebApplication.CreateBuilder(args);

アプリをビルドするための Builder (WebApplicationBuilder) を作成します。

ではこの Builder が何をするかというと
ソースコードドキュメントを見る感じ、以下のようなことを行っているように見えます。
(聞き慣れないワードが出てきているかもしれませんが、今後のブログにて解説する予定です。)

  1. 新しい構成ソースとプロバイダーを追加する
  2. Hostされる環境の情報を取得する
  3. ログプロバイダーを追加する
  4. DIで用いるサービスを追加する
  5. HostとWebHostを構成する

なおASP.NET Core5.0 以前では、以下のように書かれていた箇所に該当します。

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

    //ここの部分
    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup();
}

この時、6.0以降のWebApplication.CreateBuilder()と、5.0以前のCreateWebHostBuilder.Build()を比較すると、

「ASP.NET 5.0も6.0以降も同じ処理って言ってたのにApplicationのビルダーなのかWebHostのビルダーなのかで何か違うじゃん」
といったように感じる方もいられるかもしれません。

このあたりがまだ追い切れていないのですが、以下の記事が非常に参考になりました。

Comparing WebApplicationBuilder to the Generic Host

これを踏まえての自分の解釈にはなるのですが、

ASP.NET Core 5.0以前においては

Program.cs アプリケーションの起動とライフタイムを管理するためのWebHostを構築するコードが含まれる
Startup.cs

パイプラインなどのApplicationの要素を構築するコードが含まれる
(パイプラインに関してはまた今後のブログで紹介していく予定です。)

こちらに書きました。

という区分けになっていたように見えます。

ただ、これらがひとつのProgram.csファイルに統一されるようなになったため
HostのBuilderではなく、Hostを含むApplication全体のBuilderとして実装され、実装が異なっていると考えました。

ただ機能としては同じであり、WebApplicationBuilderのプロパティとしてもHost, WebHostが含まれていることがわかります。
そのため、WebApplicationBuilderを通してHostやWebHostの構成も可能です。

イメージとしてはWebHostBuilderをWebApplicationBuilderでラップしているような感じでしょうか。

次に進みます。

DIコンテナへのサービス追加

// Add services to the container.
builder.Services.AddControllersWithViews();

ここに書かれているコードは、DI コンテナにサービスを追加しているものになります。
DI コンテナ周りについては追ってブログで紹介したいと思うので、本記事では割愛します。

なおこのコードは、以前のバージョンでいうところの Startup.csクラスのConfigureServicesメソッドで記載している箇所に該当します。

次に進みます。

WebApplicationインスタンスの作成

var app = builder.Build();

ここでWebApplicationBuilderを利用して、WebApplicationのインスタンスを作成します。

このWebApplicationのインスタンスは以下のような仕事をします。

  1. ミドルウェアパイプラインの構築
  2. アプリケーションの開始

続くコードで実際にこれらの処理を実装していきます。

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

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


app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

ここでは利用するミドルウェアを指定し、パイプラインを構築します。
この時、ミドルウェアが実行される順番は重要であるため、コードを記載する順番には気を付ける必要があります。

また、上の図のstep4にて

4. リクエストは ASP.NET Core ミドルウェアパイプラインにて処理されます

と書きましたが、この処理するパイプラインを構成しているのがここのソースコードになります。

また、こちらのコードはASP.NET Core 5以前のバージョンでいうところの Configureメソッドで記載している箇所に該当します。

アプリの開始

app.Run();

このコードによって、サーバーおよびアプリケーションを起動し、ホストが終了するまで呼び出し元のスレッドをブロックします。

Program.csソースコードの中身としては以上となります。

まとめ

今回は.NET 8.0におけるASP.NET CoreのProgram.csの中身を見てみました。

ざっくりとまとめると

  • ASP.NET Core 6にて採用された最小ホスティングモデルにより、Startup.csファイルとProgram.csファイルが統合された
    • ただし、機能的に違いはなくどちらを採用してもよい
  • Program.csに書かれている内容としては、コンソールアプリケーションのソースコードである
  • コンソールアプリケーションによってホストが構成がされたのちに、実際にサーバーおよびアプリが開始される
  • リクエストはIIS→IISHTTPServer→Middleware Pipeline→ApplicationCodeといった順で処理される

といった感じです。

次回以降の記事では、リクエストパイプラインや、ルーティング周りなどをもう少し詳細にみていきたいと思います。
ではまた!

参考文献

ASP.NET Core の概要

Comparing WebApplicationBuilder to the Generic Host

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

1人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です