次の方法で共有


ASP.NET 5

ASP.NET 5 ランタイムの詳細

Daniel Roth

マイクロソフトは昨年 11 月、Microsoft .NET Framework を使用した最新の Web およびクラウド アプリケーションをビルドするための新しいオープン ソースかつクロス プラットフォーム対応のフレームワークとして、ASP.NET 5 を発表しました。筆者が所属する ASP.NET 開発チームは、ニューヨークで開催された Connect(); イベントにおいて、Visual Studio 2015 Preview と併せて ASP.NET 5 Preview をリリースしました。2014 年 12 月 15 日発行の MSDN Magazine の特別号に掲載された「ASP.NET 5 Preview の概要」(bit.ly/1K4PY4U、英語) の中で、ASP.NET 5 ランタイムとその新しい Visual Studio プロジェクト システムを紹介しました。前回 12 月に ASP.NET 5 について紹介してから、 ASP.NET 5 のプレビュー版をさらに 2 つリリースしています。Beta2 を Visual Studio 2015 CTP 5 のリリース時に、Beta3 を Visual Studio 2015 CTP 6 のリリース時に発表しました。そして、リリースを重ねるごとに、ASP.NET は進化し、機能が向上しています。そういった機能強化の多くは、GitHub (bit.ly/1DaY7Cd、英語) のパブリック ASP.NET プロジェクトを通じて、.NET コミュニティの皆さんの多大なるご協力によりもたらされました。今回は、新しい ASP.NET 5 ランタイムの内部処理を詳しく説明し、この最新リリースでの変更点を紹介します。

K Runtime Environment (KRE)

12 月号で説明したように、ASP.NET 5 は、いくつかある .NET CLR の 1 つをホストできる柔軟なクロス プラットフォーム対応ランタイムを基盤にしています。ASP.NET 5 の API がフルセットで利用できるため、互換性を最大限確保して、.NET Framework ベースの ASP.NET 5 アプリケーションを実行できます。また、新しい .NET Core ベースの ASP.NET 5 も実行できます。.NET Core は、コンピューター上の環境を一切変更することなく、既存の環境にパッケージをコピーするだけで配置できる、正真正銘のサイド バイ サイド展開を実現します。いずれは、.NET Core でも ASP.NET 5 のクロス プラットフォーム対応が実現される予定です。現在は、コミュニティにより Mono でのクロス プラットフォーム対応がサポートされています。

ASP.NET 5 のランタイム ホスト インフラストラクチャは、現在 K Runtime Environment (KRE) と呼ばれていますが、これは正式名称を決定するまでの通称です。KRE は、ホスト プロセス、CLR ホスト ロジック、マネージ エントリ ポイント検出機能など、.NET アプリケーションの実行に必要なものがすべて揃っている環境を提供します。KRE はクロス プラットフォーム対応の .NET Web アプリケーションを実行するために作成されていますが、コンソール アプリケーションなど、他の種類の .NET アプリケーションも実行できます。KRE は、.NET 開発者が精通しているものと同じ .NET CLR と基本クラス ライブラリを基盤にしつつ、Windows、OS X、Linux で .NET アプリケーションを実行できるクロス プラットフォーム対応も実現しています。

論理的には、KRE の機能は 5 レイヤーで構成されています。以下では、各レイヤーとその機能について説明します。

レイヤー 1 - ネイティブ プロセス: ネイティブ プロセスはネイティブの CLR ホストを検索して呼び出す非常に薄い層で、スタックなどの要素が使用できるように、プロセスに提供された引数を渡します。Windows ではネイティブの実行可能ファイル (klr.exe) がこれに該当し、Mac または Linux では Bash 実行可能スクリプトになります。IIS での実行は、新しいネイティブ HTTP モジュールか、Helios ローダーを使用して、処理されます。Helios ローダーは .NET Framework 4.5.1 の拡張性フックを利用することで、新しい IIS モジュールをインストールしなくても KRE をブートストラップできます。ネイティブ HTTP モジュールがあれば、.NET Framework に依存することなく、.NET Core ベースの Web アプリケーションを IIS で実行できます。ネイティブ HTTP モジュールは現時点では公開していませんが、将来のプレビュー版でリリースする予定です。

レイヤー 2 と 3 - ネイティブ CLR ホストと CLR: ネイティブ CLR ホストには、次の 3 種類の基本機能があります。

  1. CLR を起動します。起動するしくみは、CLR のバージョンによって異なります。たとえば、.NET Core を起動するには、coreclr.dll を読み込み、ランタイムを構成して起動し、すべてのマネージ コードを実行する AppDomain を作成します。Mono や .NET Framework 4.5.1 の場合は、これとはプロセスがやや異なりますが、結果は同じです。
  2. マネージ エントリ ポイント (次のレイヤー) を呼び出します。
  3. ネイティブ ホストのエントリ ポイントが返されると、このプロセスによって CLR がクリーン アップされ、シャット ダウンされます。つまり、アプリケーション ドメインがアンロードされ、ランタイムが停止されます。

レイヤー 4 - マネージ エントリ ポイント: このレイヤーは、初めてマネージ コードで書かれたレイヤーです。機能は次のとおりです。

  1. アセンブリを読み込み、ライブラリ フォルダーの依存関係を満たします。
  2. IApplicationEnvironment と依存関係の挿入のコア インフラストラクチャをセットアップします。
  3. 指定されたアプリケーションの Main エントリ ポイントまたはアプリケーション ホストを呼び出します。

このレイヤーでは、アプリケーションのベース パスまたは指定されたライブラリ フォルダーからしか、アセンブリは読み込まれません。NuGet パッケージや、さらには実行時にコンパイルされるコードの依存関係を解決するための他のローダーを追加するのは、次のレイヤーです。

レイヤー 5 - アプリケーション ホスト/アプリケーション: 開発者がディスク上でアプリケーション全体をアセンブリにコンパイルして、ライブラリ フォルダーに格納する場合、このレイヤーがアプリケーション (エンド ユーザーが認識するアプリケーション) になります。この処理を行う場合は、レイヤー 1 の起動時にアプリケーションをコンパイルして、標準の Main エントリ ポイントがある DLL の名前を渡します。

ただし、ほとんどの状況では、アプリケーション ホストを利用して、アプリケーションの依存関係を解決し、アプリを実行します。KRE に用意されているアプリケーション ホストは Microsoft.Framework.ApplicationHost で、次の機能を提供しています。

  1. project.json の依存関係を調べ、アプリケーションが使用する依存関係のクロージャーを構築します。依存関係を調べるロジックについて詳しくは、bit.ly/1y5lZEm (英語) をご覧ください。
  2. インストール済みの NuGet パッケージ、Roslyn を使用して実行時にコンパイルされるソースなど、さまざまなソースからアセンブリを読み込むことができるその他のアセンブリ ローダーを追加します。
  3. ネイティブ プロセスの起動時に引数として渡された名前のアセンブリのエントリ ポイントを呼び出します。このアセンブリは、ApplicationHost が読み込むことができるエントリ ポイントがあるものであれば、どのようなものでもかまいません。KRE に付属の ApplicationHost は、void Main パブリック メソッドを検索できます。これは ASP.NET ホスト レイヤーのセットアップに使用されるエントリ ポイントです。このレイヤーは Web アプリケーションの Startup.cs を検索し、Configure メソッドを実行できます。

KRE について学習する際に 1 つ注意しなければならないことは、KRE はスタックの低レベルの構成要素であることです。KRE レベルでは、依然としてダイナミック リンク ライブラリ (DLL) の検索と読み込みが中心的な処理になります。アプリケーション レベルで、パッケージやその他の最上位の依存関係を考慮できるロジックは、この KRE に保持されています。

クロス プラットフォーム SDK ツール

KRE のパッケージには、クロス プラットフォーム対応 .NET アプリケーションのビルドに必要なものがすべて揃っている SDK も含まれています。前回の ASP.NET 5 についてのコラムでは、KRE Version Manager (KVM) ツールを使ってコンピューターにインストールされている KRE を検出する方法や、新しい KRE をインストールする方法、使用する KER を選択する方法を説明しました。各 OS 用の KVM のインストール方法については、bit.ly/1y5mqyi (英語) をご覧ください。

KVM は、KRE_FEED 環境変数を使って構成されている NuGet フィードから KRE をインストールします。KRE は、これまで利用してきたパッケージとは異なるという意味で、従来の NuGet パッケージではありません。NuGet は KRE の配布とバージョン管理を行うための便利な手段にすぎません。既定では、KRE は、%USERPROFILE%\.k\runtimes に KRE .zip ファイルをコピーして展開することで、インストールします。

また、前回は、NuGet パッケージのインストール、復元、作成を行う K Package Manager (KPM) ツールを紹介しました。KPM ツールは名前を nuget に変更して、既存の NuGet クライアントとの整合性を取る予定です。この整合性を取るための取り組みの一環として、kpm サブコマンドの一部は既に名前が変更されています。現在は、公開するアプリケーションのバンドルには bundle コマンドを使用し、プロジェクトの NuGet パッケージのビルドと作成には pack コマンドを使用します。新しくなった build コマンドでは、何もパッケージすることなく、未加工のビルドを出力します。また、project.json 内の既存の csproj ベースのプロジェクトを参照する手段となる新しい wrap コマンドもあります。現在、パッケージは、既定では %USERPROFILE%\.k\packages フォルダーにインストールされるようになりましたが、global.json ファイルで packages フォルダーのパスを設定することで、インストール先を制御できます。

クロス プラットフォーム対応 .NET コンソール アプリケーション

ここでは、KRE を使って簡単なクロス プラットフォーム対応 .NET コンソール アプリケーションを作成する方法を紹介します。最初に、エントリ ポイントがある DLL を作成する必要があります。それには、Visual Studio 2015 の ASP.NET 5 Console Application プロジェクト テンプレートを使用できます。コードは次のようになります。

public class Program
{
  public void Main(string[] args)
  {
    Console.WriteLine("Hello World");
    Console.ReadLine();
  }
}

これはごく一般的なコードのように思えますが、エントリ ポイントがインスタンス メソッドであることに注意してください。KRE は、静的な Program.Main エントリ ポイントの他に、インスタンス ベースのエントリ ポイントもサポートします。さらに、Main エントリ ポイントを非同期にして、Task を返すこともできます。Main エントリ ポイントにインスタンス メソッドを使用することで、ランタイム環境によってサービスをアプリケーションに挿入できます。

このアプリケーションは Visual Studio から実行することも、コマンド ラインでアプリケーションの project.json ファイルがあるディレクトリから "k run" を実行することで、実行することもできます。K コマンドはシンプルなバッチ ファイルにすぎず、"k run" コマンドは次のように拡張できます。

klr.exe --appbase . Microsoft.Framework.ApplicationHost run

K コマンドはネイティブ プロセス (klr.exe) を実行し、アプリケーション ベースを現在のディレクトリに指定して、既定のアプリケーション ホストを指定します。ネイティブ プロセスには、既定のアプリケーション ホストについての特定の情報はありません。単純に Microsoft.Framework.ApplicationHost アセンブリの標準のエントリ ポイントを検索し、このエントリ ポイントを呼び出します。

既定のアプリケーション ホストを使用しない場合は、ネイティブ レイヤーを起動して、直接アプリケーションを呼び出すことができます。それには、まず、コンソール アプリケーションの DLL を生成するプロジェクトをビルドします。このときは必ず、プロジェクトのプロパティの [ビルド] タブで [Produce outputs on build] (ビルド開始時に出力ウィンドウを表示する) チェック ボックスをオンにしてください。ビルドは、ソリューション フォルダーの artifacts ディレクトリに出力されます。使用する KRE 用の組み込みの DLL が含まれるディレクトリに移動し、"klr.exe <DLL 名>" を呼び出して、コンソール アプリケーションからの出力がどのようになるか確認してみましょう。

DLL を直接起動するのは、非常に低レベルで未加工のアプリケーション作成方法です。既定のアプリケーション ホストを使用しないため、project.json のサポートと NuGet ベースの依存性管理のサポートを割愛できます。代わりに、利用するライブラリは、指定されたライブラリ フォルダーから読み込まれます。今回の説明では、既定のアプリケーション ホストを使用します。

IServiceManifest サービスを使用して、ランタイム環境から利用できるすべてのサービスを列挙できます。このアセンブリは Assembly Neutral Interface (ANI) であるため、これを使用するために追加の依存関係を指定する必要はまったくありません。ANI は名前と名前空間だけで特定される型で、KRE の機能の 1 つです。別々のアセンブリに含まれていても、名前と名前空間が同じである 2 つの ANI (アセンブリに中立な型) は、同じものであると見なされます。つまり、共通コンポーネントで依存関係を宣言する必要はなく、共通の抽象化をローカルで宣言できます。

コンソール アプリケーションに、アセンブリに中立的な独自の IServiceManifest インターフェイスを定義するには、次のようなコードを作成します。

namespace Microsoft.Framework.DependencyInjection.ServiceLookup
{
  [AssemblyNeutral]
  public interface IServiceManifest
  {
    IEnumerable<Type> Services { get; }
  }
}

しかし、AssemblyNeutralAttribute はどこから取得されるのでしょう。AssemblyNeutralAttribute も、もちろんアセンブリに中立的であるので、ローカルで宣言できます。

namespace Microsoft.Net.Runtime
{
  [AssemblyNeutral]
  [AttributeUsage(AttributeTargets.All, 
    Inherited = false, AllowMultiple = true)]
  public sealed class AssemblyNeutralAttribute : Attribute
  {
  }
}

これらのアセンブリに中立的な型 (ANI) は、KRE が使用している同じ型と実行時に連携されます。

図 1 のコードでは、Program クラスにコンストラクターを追加し、各サービスでこの処理を反復することで、IServiceManifest サービスをアプリケーションに挿入しています。

図 1 アプリケーションへの IServiceManifest サービスの挿入

namespace ConsoleApp1
{
  public class Program
  {
    public Program(IServiceManifest serviceManifest)
    {
      ServiceManifest = serviceManifest;
    }
    IServiceManifest ServiceManifest { get; }
    public void Main(string[] args)
    {
      foreach (Type type in ServiceManifest.Services)
      {
        Console.WriteLine(type.FullName);
      }
    }
  }
}

アプリケーション ホストは project.json のサポートを有効にし、(NuGet パッケージ、プロジェクト参照などを処理するための) その他のアセンブリ リゾルバーを追加して、複数の追加のサービスをアプリケーションで利用できるようにしてから、アプリケーションのエントリ ポイントを呼び出します。この時点でコンソール アプリケーションを実行すると、次のような出力が生成されます。

Microsoft.Framework.Runtime.IAssemblyLoaderContainer
Microsoft.Framework.Runtime.IAssemblyLoadContextAccessor
Microsoft.Framework.Runtime.IApplicationEnvironment
Microsoft.Framework.Runtime.IFileMonitor
Microsoft.Framework.Runtime.IFileWatcher
Microsoft.Framework.Runtime.ILibraryManager
Microsoft.Framework.Runtime.ICompilerOptionsProvider
Microsoft.Framework.Runtime.IApplicationShutdown

ファイルの監視、アプリケーションの "ライブラリ" の構造 (プロジェクト、パッケージ、アセンブリ) の走査、使用するコンパイル オプションの取得、アプリケーションのシャットダウンを行うためのサービスがあります。ただし、ASP.NET 5 と KRE はまだプレビュー版で、現在開発中であるため、実際に提供されているサービスは異なる可能性があります。

ホスト

ASP.NET ホスト レイヤーは KRE の上で稼働し、アプリケーションを実行する Web サーバーの検索、アプリケーションの起動ロジックの検索、サーバーでのアプリケーションのホスト、アプリケーションのシャットダウン時のクリーンアップを行います。また、ホスト関連のさまざまな追加のサービスをアプリケーションに提供します。

ASP.NET ホスト DLL (Microsoft.AspNet.Hosting、bit.ly/­1uB6ulW、英語) には、KRE アプリケーション ホストによって呼び出されるエントリ ポイント メソッドがあります。--server コマンド ライン オプション、または config.json や環境変数など、その他の構成データのソースを指定することで、使用する Web サーバーを構成できます。ホスト レイヤーは、その後、指定されたサーバー アセンプリ/型を読み込んで、サーバーの初期化と起動に使用できる IServerFactory を検索します。通常、サーバーが読み込まれるには、project.json で依存関係として指定されている必要があります。

project.json で定義するコマンドは、klr.exe に渡される追加のコマンドライン引数にすぎません。たとえば、既定の ASP.NET Starter Web App プロジェクト テンプレートでは、次のようなコマンドが多数 project.json に含まれています。

"commands": {
  /* Change the port number when you are self hosting this application */
  "web": "Microsoft.AspNet.Hosting 
    --server Microsoft.AspNet.Server.WebListener
    --server.urls http://localhost:5000",
  "gen": "Microsoft.Framework.CodeGeneration",
  "ef":  "EntityFramework.Commands"
},

したがって、"k web" を実行する場合、実際には次のコードが実行されます。

klr.exe --appbase . Microsoft.Framework.ApplicationHost Microsoft.AspNet.Hosting
  --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5000

起動

ASP.NET ホスト レイヤーは、アプリケーションの起動ロジックも検索します。通常、アプリケーションの起動ロジックは Startup クラスにより定義します。Configure メソッドを使って要求パイプラインをセットアップし、ConfigureServices メソッドを使ってアプリケーションに必要なサービスを構成します (図 2 参照)。

図 2 Startup クラス

namespace WebApplication1
{
  public class Startup
  {
    public void ConfigureService(IServiceCollection services)
    {
      // Add services for your application here
    }
    public void Configure(IApplicationBuilder app)
    {
      // Configure your application pipeline here
    }
  }
}

Configure メソッドで IApplicationBuilder インターフェイスを使用して、アプリケーションの要求パイプラインを作成します。IApplicationBuilder には、ミドルウェアを使用するメソッド (Use)、アプリケーション ビルダーを新規作成するメソッド (New)、要求デリゲートを構築するメソッド (Build) があります。要求デリゲートは、ASP.NET 5 のコア ランタイム コンストラクトです。要求デリゲートは HttpContext を取得し、非同期で特定の処理を実行します。

public delegate Task RequestDelegate(HttpContext context);

ASP.NET 5 ミドルウェアは、パイプライン内の次の要求デリゲートを入力として取得し、ミドルウェアのロジックを使用して特定の要求デリゲートを提供します。この返された要求デリゲートが、パイプライン内の次の要求デリゲートを呼び出すかどうかは決まっていません。次の要求デリゲートを呼び出さないミドルウェア ロジックをすばやく実行するには、IApplicationBuilder で Run 拡張メソッドを使用できます。

app.Run(async context => await context.Response.WriteAsync("Hello, world!"));

これは、次のパラメーターを無視する、以下のインライン ミドルウェアを作成するのと同じことになります。

app.Use(next => async context =>
  await context.Response.WriteAsync("Hello, world!"));

再利用可能なミドルウェアを作成するには、原則として、ミドルウェアに必要な追加のサービスまたはパラメーターと併せて、次の要求デリゲートをコンストラクトに挿入するクラスとしてミドルウェアを記述します。その後、非同期の Invoke メソッドとして、ミドルウェアの要求デリゲートを実装します (図 3 参照)。

図 3 再利用可能なクラスとしてのミドルウェアの実装

using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;
using System.Threading.Tasks;
public class XHttpHeaderOverrideMiddleware
{
  private readonly RequestDelegate _next;
  public XHttpHeaderOverrideMiddleware(RequestDelegate next)
  {
    _next = next;
  }
  public Task Invoke(HttpContext httpContext)
  {
    var headerValue =
      httpContext.Request.Headers["X-HTTP-Method-Override"];
    var queryValue =
      httpContext.Request.Query["X-HTTP-Method-Override"];
    if (!string.IsNullOrEmpty(headerValue))
    {
      httpContext.Request.Method = headerValue;
    }
    else if (!string.IsNullOrEmpty(queryValue))
    {
      httpContext.Request.Method = queryValue;
    }
    return _next.Invoke(httpContext);
  }
}

IApplicationBuilder で UseMiddleware<T> 拡張メソッドを使用することで、この原則に従ったミドルウェアを使用できます。このメソッドに渡される追加のオプションは、次の要求デリゲートと挿入サービスに続いて、ミドルウェア コンストラクターに挿入されます。原則として、次のように、ミドルウェアには専用の Use 拡張メソッドも IApplicationBuilder において定義します。

public static class BuilderExtensions
{
  public static IApplicationBuilder UseXHttpHeaderOverride(
    this IApplicationBuilder builder)
  {
    return builder.UseMiddleware<XHttpHeaderOverrideMiddleware>();
  }
}

その後、次のように、ミドルウェアをアプリケーション パイプラインに追加できます。

public class Startup
{
  public void Configure(IApplicationBuilder app)
  {
    app.UseXHttpHeaderOverride();
  }
}

ASP.NET 5 には、ビルド済みのミドルウェアが豊富に取り揃えられています。静的ファイル、ルーティング、エラー処理、診断、セキュリティを処理するためのミドルウェアがあります。マイクロソフトやコミュニティが NuGet パッケージとして提供しているミドルウェアを nuget.org (英語) から検索してダウンロードし、インストールできます。

サービスの構成

このスタックに含まれるその他のエントリ ポイントと同様に、Startup クラスでも、コンストラクターのホスト レイヤーからサービスを挿入したり、Configure メソッドや ConfigureServices メソッドの追加のパラメーターとしてサービスを指定できます。起動時に利用可能なサービスを列挙すると (IServiceManifest を使用)、利用できるサービスが増えていることがわかります。

Microsoft.Framework.Runtime.IAssemblyLoaderContainer
Microsoft.Framework.Runtime.IAssemblyLoadContextAccessor
Microsoft.Framework.Runtime.IApplicationEnvironment
Microsoft.Framework.Runtime.IFileMonitor
Microsoft.Framework.Runtime.IFileWatcher
Microsoft.Framework.Runtime.ILibraryManager
Microsoft.Framework.Runtime.ICompilerOptionsProvider
Microsoft.Framework.Runtime.IApplicationShutdown
Microsoft.AspNet.Hosting.IHostingEnvironment
Microsoft.Framework.Runtime.IProjectResolver
Microsoft.Framework.Logging.ILoggerFactory
Microsoft.Framework.Runtime.ICache
Microsoft.Framework.Runtime.ICacheContextAccessor
Microsoft.Framework.DependencyInjection.ITypeActivator
Microsoft.Framework.Runtime.IAssemblyLoadContextFactory

IHostingEnvironment サービスは、アプリケーションの Web ルート パス (通常は www フォルダー) と、Web ルートの IFileProvider 抽象化へのアクセスを提供します。IProjectResolver は、ソリューション内の他のプロジェクトの検索に使用できます。ログ サービスとキャッシュ サービス、および依存関係の挿入に対応している型のアクティベーターがあります。IAssemblyLoadContextFactory は、アセンブリの読み込みコンテキストを新規作成するための抽象化を提供します。

アプリケーション向けの既存サービスの構成や、新しいサービスの追加には、Startup クラスの ConfigureServices メソッドを使用します。ConfigureServices メソッドは IServiceCollection を取得します。IServiceCollection を使って、サービスの追加や既存サービスの変更が可能です。ASP.NET 5 には組み込みの IoC コンテナーが付属しています。IoC コンテナーは、マネージ エントリ ポイント レイヤー内に設定されていますが、これは簡単に任意のコンテナーに置き換えることができます。

フレームワークには、通常、IServiceCollection にサービスを追加するための Add 拡張メソッドが用意されています。たとえば、ASP.NET MVC 6 が使用するサービスを追加するには、次のようなコードを作成します。

public void ConfigureServices(IServiceCollection services)
{
  // Add MVC services to the services container
  services.AddMvc();
}

サービス コレクションに追加する場合、サービスは一時、スコープ、シングルトンの 3 種類のいずれかになります。一時サービスは、コンテナーから要求されるたびに作成されます。スコープ サービスは、現在のスコープに既に存在していない場合にのみ作成されます。Web アプリケーションの場合、コンテナーのスコープは要求ごとに作成されるので、要求ごとにスコープ サービスを考慮できます。シングルトン サービスは、一度だけ作成されます。

Web.config および System.Configuration スタイルの app.config ファイルは、ASP.NET 5 ではサポートされません。ASP.NET 5 には、構成データを操作するための新しい、よりシンプルな構成 API (Microsoft.Framework.ConfigurationModel、bit.ly/1yxC7gA、英語) が付属しています。新しい構成 API を使用すると、さまざまなソースから構成データを取得および操作できます。既定では JSON、XML、INI、コマンド ライン パラメーター、環境変数用の構成プロバイダーが含まれます。プロバイダーは複数指定でき、追加された順番で使用されます。環境ベースの構成をサポートすることで、アプリケーションを特定の環境に展開しやすくなります。また、アプリケーションが、その環境に適した設定をよりスムーズに選択できます。

構成データを初期化するには、目的の構成プロバイダーを Configuration の新しいインスタンスに追加します。

public Startup(IHostingEnvironment env)
{
  Configuration = new Configuration()
    .AddJsonFile("config.json")
    .AddEnvironmentVariables();
}

その後、構成値を名前で要求できます。

string user = Configuration.Get("user");
string password = Configuration.Get("password");

構成データは、options モデルを使用して厳密に型指定した形でアプリケーション全体で利用されるように指定できます。options は、構成用のさまざまなプロパティがある Plain Old C# Object (POCO) クラスにすぎません。options をアプリケーションで利用可能にするには、AddOptions を呼び出します。AddOptions を呼び出すと、IOptions<TOption> サービスがコンテナーに追加されます。依存関係の挿入がサポートされる限り、このサービスを使用して、他の種類の options にアクセスできます。

options を構成するには、IConfigureOptions<TOptions> サービスをコンテナーに追加します。IOptions<TOption> サービスの既定の実装では、IConfigure­Options<TOption> サービスをすべて収集し、それらを使用して options インスタンスを構成してから、コンシューマーに options インスタンスを提供します。options 構成ロジックを簡潔に追加するには、次のように Configure<TOption> メソッドを使用できます。

services.Configure<MvcOptions>(options => options.Filters.Add(
  new MyGlobalFilter()));

options モデルと configuration モデルは、連携して機能します。構成データは、次のように Configuration インスタンスを取得する Configure オーバーロードを使用することで、プロパティ名が一致するオプションに簡単にバインドできます。

services.Configure<MyOptions>(Configuration);

要求処理

Web サーバーは起動されると、要求のリッスンと、要求ごとのアプリケーション パイプラインの起動を開始します。サーバーは各要求を、詳細な機能インターフェイスのセットを公開するサーバー環境オブジェクトとして提示します。ファイル、Web ソケット、セッション サポート、クライアント証明書などを送信するための機能インターフェイスがあります。サポートされる機能インターフェイスの完全なリストについては、GitHub (bit.ly/1Dh7eBC、英語) をご覧ください。たとえば、以下のコードは HTTP 要求用の機能インターフェイスです。

[AssemblyNeutral]
public interface IHttpRequestFeature
{
  string Protocol { get; set; }
  string Scheme { get; set; }
  string Method { get; set; }
  string PathBase { get; set; }
  string Path { get; set; }
  string QueryString { get; set; }
  IDictionary<string, string[]> Headers { get; set; }
  Stream Body { get; set; }
}

通常は、各種機能インターフェイスに対して直接コーディングしません。Web サーバーでは機能インターフェイスを使用して、低レベルの機能をホスト レイヤーに公開します。ホスト レイヤーはそれらの機能インターフェイスを厳密に型指定した HttpContext にラップします。この HttpContext は、アプリケーションに渡されます。Web サーバー、ホスト レイヤー、およびアプリケーションをこのレベルで疎結合することで、特定のホスト モデルに限定せずに、サーバーを実装および再利用でき、アプリケーションを異なるサーバーでホストできます。ASP.NET 5 には、IIS での実行サポート (Microsoft.AspNet.Server.IIS)、HTTP.SYS シン ラッパーでの直接の実行サポート (Microsoft.AspNet.Server.WebListener)、Kestrel という新しい .NET クロス プラットフォーム対応 Web サーバー (Microsoft.AspNet.Server.Kestrel) 上での実行サポートが組み込まれています。

Open Web Interface for .NET (OWIN) コミュニティ標準 (owin.org、英語) でも、同様に、Web アプリケーションの疎結合に取り組んでいます。OWIN では、.NET サーバーとアプリケーション間の相互の通信方法を標準化しています。ASP.NET 5 は、Microsoft.AspNet.Owin パッケージ (bit.ly/15IQwA5、英語) によって OWIN をサポートしています。ASP.NET 5 は OWIN ベースの Web サーバーでホストできます (bit.ly/1DaU4FZ、英語)。また、OWIN ミドルウェアを ASP.NET 5 パイプラインで使用できます (bit.ly/1EqmoIB)。

マイクロソフトでは、当初、Katana プロジェクト (katanaproject.codeplex.com、英語) において OWIN のサポートの実装に取り組みました。ASP.NET 5 のアイデアや概念の多くはこのプロジェクトから取り入れられています。Katana には、ミドルウェア パイプラインを構築し、複数のサーバーをホストする同様のモデルがありました。ただし、低レベルの OWIN 抽象化を直接開発者に公開していた Katana とは異なり、ASP.NET 5 では OWIN をより便利でユーザーが使いやすい抽象化にブリッジしています。多少コードを追加することで、ASP.NET 5 でも OWIN ブリッジを利用して Katana のミドルウェアを使用できます (この方法については、bit.ly/1BpaXe2 (英語) の例を参照)。

まとめ

ASP.NET 5 ランタイムは、クロス プラットフォーム対応 Web アプリケーションをサポートするために、土台から開発されました。ASP.NET 5 は、.NET Framework または .NET Core で実行できる柔軟な階層型のアーキテクチャを採用しています。また、Mono を利用することでクロス プラットフォームにも対応できます (将来は .NET Core でもクロス プラットフォームに対応します)。新しい ASP.NET 5 ホスト モデルを使用すると、簡単にアプリケーションを作成し、任意の Web サーバーでアプリケーションをホストできます。ランタイム全体が、依存関係の挿入をサポートし、簡単に構成できるように開発されています。今回は新しい ASP.NET 5 について紹介しましたが、皆様のお役に立てていれば嬉しく思います。GitHub プロジェクト (github.com/aspnet/home、英語) から、ぜひフィードバックをお寄せください。また、同プロジェクトにご協力賜りますようお願い申し上げます。


Daniel Roth は、ASP.NET チームのシニア プログラム マネージャーで、現在 ASP.NET 5 を担当しています。彼の情熱は、.NET 開発と、フレームワークをシンプルで使いやすくして、ユーザーを喜ばせることに向けられています。

この記事のレビューに協力してくれたマイクロソフト技術スタッフの Glenn Condron、David Fowler、Murat Girgin、Chris Ross に心より感謝いたします。