読者です 読者をやめる 読者になる 読者になる

SourceChord

C#とXAML好きなプログラマの備忘録。最近はWPF系の話題が中心です。

.NET Coreことはじめ~その3・最小構成のWebサーバー~

.NET Core C#

今回は、.NET Coreで最小構成のWebサーバーを作ってみます。
ただし、まだASP.NET Coreのプロジェクトの雛形などは使わず、一から書き始めてみます。

参考サイト

今回は、公式ページのチュートリアルを参考に、最小構成のサーバーを実装するところまで。
https://docs.asp.net/en/latest/getting-started.html

次回以降は、↓のサンプルコードなどを参考にもう少し詳しく見ていこうと思います。
https://github.com/dodyg/practical-aspnetcore

プロジェクトの準備

プロジェクトの作成

まずは適当なフォルダを作り、そこをカレントディレクトリとして、コンソールから以下のコマンドを実行します。

dotnet new

依存パッケージの設定(project.jsonの編集)

以下のように、"Microsoft.AspNetCore.Server.Kestrel": "1.0.0"という項目を追加します。

project.json

{
  "version": "1.0.0-*",
  "buildOptions": {
    "debugType": "portable",
    "emitEntryPoint": true
  },
  "dependencies": {},
  "frameworks": {
    "netcoreapp1.0": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.0.1"
        },
        "Microsoft.AspNetCore.Server.Kestrel": "1.0.0"
      },
      "imports": "dnxcore50"
    }
  }
}

ファイルを保存したら、dotnet restoreコマンドを実行します。

コードの編集

Startupクラスの作成

Startup.csというファイルを追加し、以下のようなコードを書きます。
f:id:minami_SC:20161027234020p:plain

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

namespace aspnetcoreapp
{
    public class Startup
    {
        public void Configure(IApplicationBuilder app)
        {
            app.Run(context =>
            {
                return context.Response.WriteAsync("Hello World!!");
            });
        }
    }
}

エントリポイントの作成(Main関数)

Program.csを開き、Main関数に以下のようなコードを書きます。

Program.cs

using System;
using Microsoft.AspNetCore.Hosting;

namespace aspnetcoreapp
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = new WebHostBuilder().UseKestrel()
                                           .UseStartup<Startup>()
                                           .Build();

            host.Run();
        }
    }
}

WebHostBuilderのインスタンスを作り、各種設定を行うためのメソッドをメソッドチェーンで繋いで実行していきます。

UseStartupメソッドでは、先ほど作ったStartupクラスをジェネリック型引数に指定して実行します。
このStartupメソッド、特に何かのクラスを継承しているわけでも、インターフェースの実装をしているわけでもないですが、このStartupクラスのConfigureメソッドが呼び出されます。

内部でリフレクションでもやってるのかな、、とか思い調べてみると、この辺の動作を調べてまとめてくれている記事を見つけました。 http://ryuichi111std.hatenablog.com/entry/2016/05/29/151111

この記事を参考にして、ASP.NET CoreのHostingにかかわる部分のコードを追いかけてみました。

以下の箇所でConfigure**というような名前の関数をリフレクションで探しているようです。 https://github.com/aspnet/Hosting/blob/b6da89f54cff11474f17486cdc55c2f21f2bbd6b/src/Microsoft.AspNetCore.Hosting/Internal/StartupLoader.cs#L118-L135

これ、なんでこんな設計にしたんだろう・・・??? 普通にやるなら、何らかのインターフェースor基底クラスを定義して、その型を実装した派生型だけ受け付ける、、、とかにしそうなもんだけど・・・

実行

dotnet runコマンドを実行すると、Webサーバーが起動します。
f:id:minami_SC:20161027234118p:plain

5000番ポートでリッスンしているので、ブラウザで以下のアドレスにアクセスすると、Startupクラスで書いた内容(ここでは「Hello World!!」)が表示されます。
f:id:minami_SC:20161027234128p:plain

今日はここまで。