次の方法で共有


プロジェクト Katana の概要

作成者: Howard Dierking

ASP.NET Framework の歴史は 10 年を超え、このプラットフォームにより、数え切れないほどの Web サイトとサービスが開発されてきました。 Web アプリケーション開発戦略が進化するにつれて、ASP.NET MVC や ASP.NET Web API などのテクノロジとともに、フレームワークも段階的に進化してきました。 Web アプリケーション開発が、次の進化の一歩としてクラウド コンピューティングの世界に足を踏み入れるときに、プロジェクト Katana は、基盤となるコンポーネントのセットを ASP.NET アプリケーションに提供して、柔軟性、移植性、軽量性、パフォーマンスの向上を実現します。言い換えると、プロジェクト Katana クラウドは、お使いの ASP.NET アプリケーションを最適化します。

なぜ今 Katana なのか

議論の対象が開発者フレームワークなのか、エンドユーザー製品なのかに関係なく、製品を作成するための根本的な動機を理解することは重要で、その一部として、製品の対象ユーザーを把握することが含まれます。 ASP.NET は当初、2 種類の顧客を念頭に置いて作成されました。

最初の顧客グループは、従来の ASP 開発者でした。 当時、ASP は、マークアップとサーバー側スクリプトを組み合わせることによって、動的なデータドリブン Web サイトとアプリケーションを作成するための主要なテクノロジの 1 つでした。 ASP ランタイムは、基になる HTTP プロトコルと Web サーバーの主要な側面を抽象化し、セッションやアプリケーションの状態管理、キャッシュなどの追加サービスへのアクセスを提供する、一連のオブジェクトを含むサーバー側スクリプトを提供しました。強力な従来の ASP アプリケーションは、サイズと複雑さが増すにつれて、管理が難しくなりました。 これは主に、スクリプト環境で見つかった構造の欠如と、コードとマークアップのインターリーブによるコードの重複が組み合わせられること原因でした。 ASP.NET は、いくつかの課題に対処しながら、従来の ASP の長所を活用するために、.NET Framework のオブジェクト指向言語によって提供されるコード編成を活用しながら、従来の ASP 開発者が慣れ親しんだサーバー側プログラミング モデルも維持しました。

ASP.NET のターゲット顧客の 2 番目のグループは、Windows ビジネス アプリケーション開発者でした。 HTML マークアップと、より多くの HTML マークアップを生成するためのコードの記述に慣れていた従来の ASP 開発者とは異なり、WinForms 開発者 (以前の VB6 開発者など) は、キャンバスと豊富なユーザー インターフェイス コントロールを含むデザイン時のエクスペリエンスに慣れていました。 ASP.NET の最初のバージョン ("Web Forms" とも呼ばれる) は、同様の設計時エクスペリエンスと、ユーザー インターフェイス コンポーネント用のサーバー側イベント モデルと、一連のインフラストラクチャ機能 (ViewState など) を提供して、クライアント側とサーバー側のプログラミングの間にシームレスな開発者エクスペリエンスを作成しました。 Web Forms は、WinForms 開発者にとってなじみのあるステートフル イベント モデルの下で、Web のステートレスな性質を効果的に隠しました。

過去のモデルで生じた課題

結果として、成熟した豊富な機能を持つランタイムおよび開発者プログラミング モデルが形成されました。 しかし、その機能の豊富さによって、いくつかの重要な課題が発生しました。 まず、フレームワークがモノリシックになり、論理的に異なる機能の単位が同じ System.Web.dll アセンブリに密に結合されました (たとえば、Web フォーム フレームワークを持つコア HTTP オブジェクト)。 第 2 に、ASP.NET はより大規模な .NET Framework の一部として含まれていました。このことは、リリースの間隔が数年ほどになることを意味しました。これにより、急速に進化する Web 開発で発生するすべての変更に ASP.NET が対応することが困難になりました。 最後に、System.Web.dll 自体が、特定の Web ホスティング オプション (インターネット インフォメーション サービス (IIS)) といくつかの異なる方法で結合されました。

進化のステップ: ASP.NET MVC と ASP.NET Web API

その後、Web 開発は大きく変わりました。 Web アプリケーションは、大規模なフレームワークではなく、一連の小さな集中型コンポーネントとして開発されていくようになりました。 コンポーネントの数とリリース頻度は、これまでにない速度で増加していました。 Web のペースに遅れずに着いていくには、フレームワークを、サイズが大きく機能が豊富なものではなく、より小さく分離され、集中型にする必要があるのは明らかでした。そのため、ASP.NET チームは、ASP.NET を、単一のフレームワークではなく、プラグ可能な Web コンポーネントのファミリにするために、いくつかの進化的なステップを実行しました

初期の変化の 1 つは、Ruby on Rails などの Web 開発フレームワークのおかげでよく知られる Model-View-Controller (MVC) 設計パターンの人気の高まりです。 このスタイルの Web アプリケーションの構築により、開発者は、マークアップとビジネス ロジックの分離を維持しながら、アプリケーションのマークアップをより詳細に制御できました。これは、ASP.NET の最初のセールス ポイントの 1 つでした。 このスタイルの Web アプリケーション開発の需要を満たすために、Microsoft は、将来に備えて、ASP.NET MVC を帯域外で (.NET Framework に含めず) 開発することにしました。 ASP.NET MVC は独立したダウンロードとしてリリースされました。 これにより、エンジニアリング チームは、以前に可能だったよりもはるかに頻繁に更新プログラムを配信する柔軟性を獲得しました。

Web アプリケーション開発におけるもう 1 つの大きな変化は、AJAX 要求を介してバックエンド Web API と通信するクライアント側スクリプトから生成されたページの動的セクションを含む、動的なサーバー生成 Web ページから静的な初期マークアップへの移行でした。 このアーキテクチャの移行は、Web API の台頭と、ASP.NET Web API フレームワークの開発を推進するのに役立ちました。 ASP.NET MVC の場合と同様に、ASP.NET Web API のリリースにより、モジュール化されたフレームワークとして ASP.NET をさらに進化させる機会が提供されました。 エンジニアリング チームはこの機会を利用し、ASP.NET Web API を構築しました。これにより、System.Web.dll にあるコア フレームワークの種類のいずれにも依存関係を持たなくなります。 このことが、2 つのことを可能にしました。1 つ目は、ASP.NET Web API が完全に自己完結型の方法で進化する可能性があることを意味します (また、NuGet 経由で配信されるため、引き続き迅速に繰り返すことができます)。 2 つ目は、System.Web.dll への外部依存関係がないため、IIS に依存しなくなりました。ASP.NET Web API に、カスタム ホスト (コンソール アプリケーション、Windows サービスなど) で実行する機能が含められました。

未来: 軽快なフレームワーク

フレームワーク コンポーネントを互いに切り離し、NuGet でリリースすることで、フレームワークはより独立し、より迅速に反復処理できるようになりました。 さらに、Web API のセルフホスティング機能の能力と柔軟性は、サービスに小型で軽量なホストを必要とする開発者にとって非常に魅力的でした。 実際に、これは非常に魅力的で、他のフレームワークもこの機能を望んでいることが判明しました。これにより、各フレームワークが独自のベース アドレスで独自のホスト プロセスで実行され、個別に管理 (開始、停止など) する必要があるという新しい課題が生じました。 最新の Web アプリケーションでは、一般に、静的ファイルの提供、動的ページの生成、Web API、および最近のリアルタイム/プッシュ通知がサポートされます。 これらの各サービスを個別に実行して管理することを期待することは、単純に現実的ではありませんでした。

必要だったのは、開発者がさまざまなコンポーネントとフレームワークからアプリケーションを作成し、そのアプリケーションをサポート ホスト上で実行できるようにする単一のホスティング抽象化でした。

Open Web Interface for .NET (OWIN)

Ruby コミュニティの Rack によって実現される利点に着想を得て、.NET コミュニティの複数のメンバーが、Web サーバーとフレームワーク コンポーネントの間に抽象化を作成し始めました。 OWIN 抽象化の 2 つの設計目標は、シンプルであることと、他のフレームワークの種類に対して可能な限り少ない依存関係を取ったことでした。 これらの 2 つの目標は、次の点を保証するのに役立ちます。

  • 新しいコンポーネントを、より簡単に開発および使用できます。
  • アプリケーションを、ホストとプラットフォーム/オペレーティング システム全体の間でより簡単に移植できます。

結果の抽象化は、2 つのコア要素で構成されます。 1 つ目は環境ディクショナリです。 このデータ構造は、HTTP 要求と応答の処理に必要なすべての状態と、関連するサーバーの状態を格納する役割を担います。 環境ディクショナリは次のように定義されます。

IDictionary<string, object>

OWIN と互換性のある Web サーバーは、HTTP 要求と応答の本文ストリームやヘッダー コレクションなどのデータを環境ディクショナリに設定する役割を担います。 その後、アプリケーションまたはフレームワーク コンポーネントは、ディクショナリに追加の値を設定または更新し、応答本文ストリームに書き込む必要があります。

OWIN 仕様では、環境ディクショナリの型を指定するだけでなく、コア ディクショナリ キー値ペアのリストを定義します。 たとえば、次の表は、HTTP 要求に必要なディクショナリ キーを示しています。

キーの名称 値の説明
"owin.RequestBody" 要求本文があるストリーム (ある場合)。 要求本文がない場合は、Stream.Null をプレースホルダーとして使用できます。 要求本文の説明を参照してください。
"owin.RequestHeaders" 要求ヘッダーの IDictionary<string, string[]>ヘッダーの説明を参照してください。
"owin.RequestMethod" 要求の HTTP 要求メソッドを含む string ("GET""POST" など)。
"owin.RequestPath" 要求パスを含む string。 パスは、アプリケーション デリゲートの "root" に対する相対パスである必要があります。パスの説明を参照してください。
"owin.RequestPathBase" アプリケーション デリゲートの "root" に対応する要求パスの部分を含む stringパスの説明を参照してください。
"owin.RequestProtocol" プロトコルの名前とバージョンを含む string ("HTTP/1.0""HTTP/1.1" など)。
"owin.RequestQueryString" 先頭に "?" がない、HTTP 要求 URI のクエリ文字列コンポーネントを含む string (例: "foo=bar&baz=quux")。 値は空の文字列でもかまいません。
"owin.RequestScheme" 要求に使用される URI スキームを含む string ("http""https" など)。URI スキームの説明を参照してください。

OWIN の 2 番目の重要な要素は、アプリケーション デリゲートです。 これは、OWIN アプリケーション内のすべてのコンポーネント間のプライマリ インターフェイスとして機能する関数シグネチャです。 アプリケーション デリゲートの定義は次のとおりです。

Func<IDictionary<string, object>, Task>;

アプリケーション デリゲートは、関数が入力として環境ディクショナリを受け取り、Task を返す Func デリゲート型の実装にすぎません。 この設計は、開発者にとっていくつかの影響を及ぼします。

  • OWIN コンポーネントを記述するために必要な型の依存関係はごく少数です。 これにより、開発者の OWIN へのアクセシビリティが大幅に向上します。
  • 非同期設計により、コンピューティング リソースの処理 (特に I/O 集中型操作の場合) で抽象化を効率的に行うことができます。
  • アプリケーション デリゲートはアトミックな実行単位であり、環境ディクショナリはデリゲートのパラメーターとして実行されるため、OWIN コンポーネントを簡単に連結して複雑な HTTP 処理パイプラインを作成できます。

実装の観点からは、OWIN は仕様 (http://owin.org/html/owin.html) です。 その目標は、次の Web フレームワークになることではなく、Web フレームワークと Web サーバーの対話方法の仕様になることです。

OWIN または Katana を調査した場合は、Owin NuGet パッケージと Owin.dll にも気付いたかもしれません。 このライブラリには、1 つのインターフェイス [IAppBuilder]/dotnet/api/microsoft.aspnetcore.builder.iapplicationbuilder) が含まれています。このインターフェイスは、OWIN 仕様のセクション 4 で説明されているスタートアップ シーケンスを形式化および変換します。 OWIN サーバーをビルドするためには必要ありませんが、[IAppBuilder]/dotnet/api/microsoft.aspnetcore.builder.iapplicationbuilder) インターフェイスは具体的な参照ポイントを提供し、Katana プロジェクト コンポーネントによって使用されます。

プロジェクト Katana

OWIN 仕様と Owin.dll の両方がコミュニティ所有であり、コミュニティがオープン ソースの取り組みを実行するのに対し、Katana プロジェクトは、オープン ソースでありながら Microsoft によってビルドおよびリリースされる OWIN コンポーネントのセットです。 これらのコンポーネントには、ホストやサーバーなどのインフラストラクチャ コンポーネントと、認証コンポーネントや、SignalRASP.NET Web API などのフレームワークへのバインドなどの機能コンポーネントの両方が含まれます。 このプロジェクトには、次の 3 つの大まかな目標があります。

  • ポータブル – 新しいコンポーネントが使用可能になったときに、コンポーネントを簡単に置き換えることができる必要があります。 これには、フレームワークからサーバーとホストまで、すべての種類のコンポーネントが含まれます。 この目標の影響は、サード パーティのフレームワークが Microsoft サーバーでシームレスに実行できるのに対し、Microsoft フレームワークはサード パーティのサーバーとホストで実行される可能性があるということです。
  • モジュール式/柔軟性 – 既定でオンになっている多数の機能を含む多くのフレームワークとは異なり、Katana プロジェクト コンポーネントはコンパクトな集中型であるため、アプリケーションで使用するコンポーネントの決定を、アプリケーション開発者が管理できます。
  • 軽量/パフォーマンス/スケーラブル – フレームワークの従来の概念を、アプリケーション開発者によって明示的に追加される小さな集中コンポーネントのセットに分割することで、結果として得られる Katana アプリケーションが消費する計算リソースが少なくなり、他の種類のサーバーやフレームワークよりも多くの負荷を処理できます。 アプリケーションの要件により、基になるインフラストラクチャからより多くの機能が必要になるので、それらを OWIN パイプラインに追加できますが、これはアプリケーション開発者側で明示的に決定する必要があります。 さらに、下位レベルのコンポーネントを置き換えられるため、それらが利用可能になると、新しいハイ パフォーマンス サーバーをシームレスに導入して、これらのアプリケーションを中断することなく OWIN アプリケーションのパフォーマンスを向上させることができることを意味します。

Katana コンポーネントの概要

最初に導入されたとき、すぐに人々の注目を集めた Node.js フレームワークの一つの側面は、Web サーバーを作成して実行できるシンプルさでした。 Katana の目標が Node.js の観点から形成されているとした場合、Katana は、開発者が ASP.NET Web アプリケーションの開発について知っているすべてを投げ出すことなく、Node.js (およびそのようなフレームワーク) の利点の多くをもたらすと言えます。 この表現が正しいならば、Katana プロジェクトの使用を開始することは、Node.js の本質と等しく、簡単であるはずです。

"Hello World!" の作成

JavaScript と .NET 開発の主な違いの 1 つは、コンパイラの存在 (または不在) です。 そのため、単純な Katana サーバーの開始点は Visual Studio プロジェクトです。 ただし、最小限のプロジェクトの種類である、空の ASP.NET Web アプリケーションから始めることができます。

Screenshot of the ASP.Net Project - WebApplication1 menu, depicting how to Get Started Window Pane to create a 'Hello World' project. Shows a window with different templates to select from and the options to add core references and unit tests.

次に、Microsoft.Owin.Host.SystemWeb NuGet パッケージをプロジェクトにインストールします。 このパッケージは、ASP.NET 要求パイプラインで実行される OWIN サーバーを提供します。 これは、NuGet ギャラリーにあり、Visual Studio パッケージ マネージャー ダイアログまたはパッケージ マネージャー コンソールで次のコマンドを使用してインストールできます。

install-package Microsoft.Owin.Host.SystemWeb

Microsoft.Owin.Host.SystemWeb パッケージをインストールすると、いくつかの追加パッケージが依存関係としてインストールされます。 これらの依存関係の 1 つは Microsoft.Owin で、OWIN アプリケーションを開発するためのいくつかのヘルパー型とメソッドを提供するライブラリです。 これらの型を使用して、次の "hello world" サーバーをすばやく記述できます。

public class Startup
{
   public void Configuration(IAppBuilder app)
   {
      app.Run(context =>
      {
         context.Response.ContentType = "text/plain";
         return context.Response.WriteAsync("Hello World!");
      });
   }
}

この非常に単純な Web サーバーは、Visual Studio の F5 コマンドを使用して実行できるようになり、デバッグの完全なサポートが含まれています。

ホストの切り替え

既定では、前の "hello world" の例は、IIS のコンテキストで System.Web を使用する ASP.NET 要求パイプラインで実行されます。 これにより、IIS の管理機能と全体的な成熟度を備えた OWIN パイプラインの柔軟性と構成可能性の恩恵を受けることができるため、それ自体が大きな価値を生み出すことができます。 ただし、IIS によって提供される利点が必要ではなく、より小さく軽量なホストが望まれる場合があります。 それでは、IIS と System.Web の外部で単純な Web サーバーを実行するには、何が必要になるでしょうか。

移植性の目標を示すために、Web サーバー ホストからコマンド ライン ホストに移行するには、新しいサーバーとホストの依存関係をプロジェクトの出力フォルダーに追加してから、ホストを開始する必要があります。 この例では、OwinHost.exe という Katana ホストで Web サーバーをホストし、Katana HttpListener ベースのサーバーを使用します。 他の Katana コンポーネントと同様に、これらは次のコマンドを使用して NuGet から取得されます。

install-package OwinHost

コマンド ラインから、プロジェクトのルート フォルダーに移動し、単純に OwinHost.exe (対応する NuGet パッケージのツール フォルダーにインストール済み) を実行します。 既定では、OwinHost.exe は HttpListener ベースのサーバーを検索するように構成されているため、追加の構成は必要ありません。 Web ブラウザーで http://localhost:5000/ に移動すると、コンソールを介して実行されているアプリケーションが表示されます。

Screenshot of the Developer Command Promt and the browser window, showing a comparison of the commands entered on the Command Line and what the 'Hello World' Project would look like on the web browser.

Katana のアーキテクチャ

Katana コンポーネント アーキテクチャは、次に示すように、アプリケーションを 4 つの論理レイヤー (ホスト、サーバー、ミドルウェア、アプリケーション) に分割します。 コンポーネント アーキテクチャは、多くの場合、アプリケーションの再コンパイルを必要とせずに、これらのレイヤーの実装を簡単に置き換えることができるような方法で考慮されます。

Diagram of the Architectural Layers shows\ing four bars depicting the logical layers in which the application's architecture is divided.

Host

ホストは次の役割を担います。

  • 基になるプロセスを管理する。

  • サーバーの選択と、要求を処理する OWIN パイプラインの構築を行うワークフローを調整する。

    現在、Katana ベースのアプリケーションには、次の 3 つの主要なホスティング オプションがあります。

IIS/ASP.NET: 標準の HttpModule 型と HttpHandler 型を使用して、OWIN パイプラインは、ASP.NET 要求フローの一部として IIS 上で実行できます。 ASP.NET ホスティング サポートを有効にするには、Microsoft.AspNet.Host.SystemWeb NuGet パッケージを Web アプリケーション プロジェクトにインストールします。 さらに、IIS はホストとサーバーの両方として機能するため、この NuGet パッケージでは OWIN サーバー/ホストの区別が調整されます。つまり、SystemWeb ホストを使用している場合、開発者は代替サーバーの実装を置き換えることはできません。

カスタム ホスト: Katana コンポーネント スイートは、コンソール アプリケーション、Windows サービスなど、独自のカスタム プロセスでアプリケーションをホストする機能を開発者に提供します。この機能は、Web API によって提供されるセルフホスト機能に似ています。 次の例は、Web API コードのカスタム ホストを示しています。

static void Main()
{
    var baseAddress = new Uri("http://localhost:5000");

    var config = new HttpSelfHostConfiguration(baseAddress);
    config.Routes.MapHttpRoute("default", "{controller}");
       
    using (var svr = new HttpSelfHostServer(config))
    {
        svr.OpenAsync().Wait();
        Console.WriteLine("Press Enter to quit.");
        Console.ReadLine();
    }
}

Katana アプリケーションのセルフホスト セットアップは次のようになります。

static void Main(string[] args)
{
    const string baseUrl = "http://localhost:5000/";

    using (WebApplication.Start<Startup>(new StartOptions { Url = baseUrl })) 
    {
        Console.WriteLine("Press Enter to quit.");
        Console.ReadKey();
    }
}

Web API と Katana セルフホストの例の主な違いの 1 つは、Web API 構成コードが Katana セルフホストの例に含まれていない点です。 移植性と構成可能性の両方を有効にするために、Katana はサーバーを開始するコードを、要求処理パイプラインを構成するコードから分離します。 Web API を構成するコードは、クラス Startup に含まれています。これは、WebApplication.Start の型パラメーターとして追加して指定されます。

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = new HttpConfiguration();
        config.Routes.MapHttpRoute("default", "{controller}");
        app.UseWebApi(config);
    }
}

スタートアップ クラスについては、この記事で後ほど詳しく説明します。 ただし、Katana セルフホスト プロセスを開始するために必要なコードは、ASP.NET Web API セルフホスト アプリケーションで現在使用しているコードとよく似ています。

OwinHost.exe: Katana Web アプリケーションを実行するカスタム プロセスを記述する必要がある場合もあれば、多くのユーザーは、サーバーを起動してアプリケーションを実行できる事前構築済みの実行可能ファイルを起動することを好む場合もあります。 このシナリオのために、Katana コンポーネント スイートには OwinHost.exe が含まれます。 プロジェクトのルート ディレクトリ内から実行すると、この実行可能ファイルはサーバーを起動し (既定では HttpListener サーバーを使用します)、規則を使用してユーザーのスタートアップ クラスを検索して実行します。 より細かく制御するために、実行可能ファイルには多数の追加のコマンド ライン パラメーターが用意されています。

Screenshot of the Developer Command Prompt, showing an example of the Command Prompt's code as it runs the application on the server.

[サーバー]

ホストは、アプリケーションが実行されるプロセスの開始と保守を担当しますが、サーバーの役割は、ネットワーク ソケットを開き、要求をリッスンし、ユーザーが指定した OWIN コンポーネントのパイプラインを介してそれらを送信することです (既にお気付きのように、このパイプラインはアプリケーション開発者の Startup クラスで指定されています)。 現在、Katana プロジェクトには 2 つのサーバー実装が含まれています。

  • Microsoft.Owin.Host.SystemWeb: 以前に述べたように、IIS は ASP.NET パイプラインと連携してホストとサーバーの両方として機能します。 そのため、このホスティング オプションを選択すると、IIS は、プロセスのアクティブ化などのホスト レベルの懸念事項を管理し、HTTP 要求をリッスンします。 ASP.NET Web アプリケーションの場合、要求を ASP.NET パイプラインに送信します。 Katana SystemWeb ホストは、ASP.NET HttpModule と HttpHandler を登録して、HTTP パイプラインを通過する要求をインターセプトし、ユーザー指定の OWIN パイプラインを介して送信します。
  • Microsoft.Owin.Host.HttpListener: 名前が示すように、この Katana サーバーは .NET Framework の HttpListener クラスを使用してソケットを開き、開発者が指定した OWIN パイプラインに要求を送信します。 これは現在、Katana セルフホスト API と OwinHost.exe の両方で既定のサーバー選択です。

ミドルウェア/フレームワーク

既に述べたように、サーバーがクライアントからの要求を受け入れるときは、開発者のスタートアップ コードによって指定される OWIN コンポーネントのパイプラインを介してそれを渡す必要があります。 これらのパイプライン コンポーネントはミドルウェアと呼ばれます。
非常に基本的なレベルでは、OWIN ミドルウェア コンポーネントは、呼び出し可能になるように OWIN アプリケーション デリゲートを実装する必要があります。

Func<IDictionary<string, object>, Task>

ただし、ミドルウェア コンポーネントの開発と構成を簡略化するために、Katana ではミドルウェア コンポーネント用にいくつかの規則とヘルパー型がサポートされています。 これらの中で最も一般的なのは OwinMiddleware クラスです。 このクラスを使用して構築されたカスタム ミドルウェア コンポーネントは、次のようになります。

public class LoggerMiddleware : OwinMiddleware
{
    private readonly ILog _logger;
 
    public LoggerMiddleware(OwinMiddleware next, ILog logger) : base(next)
    {
        _logger = logger;
    }
 
    public override async Task Invoke(IOwinContext context)
    {
        _logger.LogInfo("Middleware begin");
        await this.Next.Invoke(context);
        _logger.LogInfo("Middleware end");
    }
}

このクラスは OwinMiddleware から派生し、パイプライン内の次のミドルウェアのインスタンスを引数の 1 つとして受け入れるコンストラクターを実装し、それを基本コンストラクターに渡します。 ミドルウェアを構成するために使用される追加の引数も、次のミドルウェア パラメーターの後にコンストラクター パラメーターとして宣言されます。

ランタイムに、ミドルウェアはオーバーライドされた Invoke メソッドを介して実行されます。 このメソッドは、型 OwinContext の 1 つの引数を受け取ります。 このコンテキスト オブジェクトは、前に説明した Microsoft.Owin NuGet パッケージによって提供され、要求、応答、環境ディクショナリへの厳密に型指定されたアクセスと、いくつかの追加のヘルパー型を提供します。

ミドルウェア クラスは、次のように、アプリケーションのスタートアップ コードで OWIN パイプラインに簡単に追加できます。

public class Startup
{
   public void Configuration(IAppBuilder app)
   {
      app.Use<LoggerMiddleware>(new TraceLogger());

   }
}

Katana インフラストラクチャは単に OWIN ミドルウェア コンポーネントのパイプラインを構築し、コンポーネントがパイプラインに参加するためにアプリケーション デリゲートをサポートする必要があるだけであるため、ミドルウェア コンポーネントの複雑さは、単純なロガーから、ASP.NET、Web API、または SignalR などのフレームワーク全体まで多岐にわたる可能性があります。 たとえば、前の OWIN パイプラインに ASP.NET Web API を追加するには、次のスタートアップ コードを追加する必要があります。

public class Startup
{
   public void Configuration(IAppBuilder app)
   {
      app.Use<LoggerMiddleware>(new TraceLogger());

      var config = new HttpConfiguration();
      // configure Web API 
      app.UseWebApi(config);

      // additional middleware registrations            
   }
}

Katana インフラストラクチャは、Configuration メソッドで IAppBuilder オブジェクトに追加された順序に基づいて、ミドルウェア コンポーネントのパイプラインを構築します。 この例では、LoggerMiddleware は、これらの要求が最終的にどのように処理されるかに関係なく、パイプラインを通過するすべての要求を処理できます。 これにより、ミドルウェア コンポーネント (認証コンポーネントなど) が、複数のコンポーネントとフレームワーク (ASP.NET Web API、SignalR、静的ファイル サーバーなど) を含むパイプラインの要求を処理できる強力なシナリオが可能になります。

アプリケーション

前の例に示すように、OWIN と Katana プロジェクトは、新しいアプリケーション プログラミング モデルとしてではなく、アプリケーション プログラミング モデルとフレームワークをサーバーとホスティング インフラストラクチャから切り離す抽象化として考える必要があります。 たとえば、Web API アプリケーションをビルドする場合、開発者フレームワークは、Katana プロジェクトのコンポーネントを使用して OWIN パイプラインでアプリケーションを実行するかどうかに関係なく、ASP.NET Web API フレームワークを引き続き使用します。 OWIN 関連のコードがアプリケーション開発者に表示される 1 つの場所は、開発者が OWIN パイプラインを構成するアプリケーションスタートアップ コードです。 スタートアップ コードでは、開発者は一連の UseXx ステートメントを登録します。通常は、受信要求を処理するミドルウェア コンポーネントごとに 1 つずつです。 このエクスペリエンスは、現在の System.Web ワールドに HTTP モジュールを登録する場合と同じ効果があります。 通常、ASP.NET Web API や SignalR などの大規模なフレームワーク ミドルウェアは、パイプラインの最後に登録されます。 認証やキャッシュ用などの横断的なミドルウェア コンポーネントは、通常、パイプラインの先頭に登録されるため、パイプラインで後で登録されたすべてのフレームワークとコンポーネントに対する要求を処理します。 ミドルウェア コンポーネントを互いに分離し、基になるインフラストラクチャ コンポーネントから分離することで、コンポーネントは異なる速度で進化し、システム全体の安定性が保たれます。

コンポーネント – NuGet パッケージ

現在の多くのライブラリやフレームワークと同様に、Katana プロジェクト コンポーネントは NuGet パッケージのセットとして提供されます。 今後のバージョン 2.0 では、Katana パッケージ依存関係グラフは次のようになります。 (画像をクリックすると大きなビューが表示されます)。

Diagram of the Components - NuGet Packages Hierarchy. This image portrays the library trees in which the frameworks are connected for the project components and get delivered via a set of NuGets.

Katana プロジェクトのほぼすべてのパッケージは、OWIN パッケージに直接または間接的に依存します。 これは、OWIN 仕様のセクション 4 で説明されているアプリケーション起動シーケンスの具体的な実装を提供する IAppBuilder インターフェイスを含むパッケージであることを覚えているかもしれません。 さらに、パッケージの多くは Microsoft.Owin に依存しています。これには、HTTP 要求と応答を操作するための一連のヘルパー型が用意されています。 パッケージの残りの部分は、ホスティング インフラストラクチャ パッケージ (サーバーまたはホスト) またはミドルウェアとして分類できます。 Katana プロジェクトの外部にあるパッケージと依存関係は、オレンジ色で表示されます。

Katana 2.0 のホスティング インフラストラクチャには、SystemWeb ベースと HttpListener ベースの両方のサーバー、OwinHost.exe を使用して OWIN アプリケーションを実行するための OwinHost パッケージ、カスタム ホスト (コンソール アプリケーション、Windows サービスなど) で OWIN アプリケーションを自己ホストするための Microsoft.Owin.Hosting パッケージが含まれています。

Katana 2.0 の場合、ミドルウェア コンポーネントは主にさまざまな認証手段を提供することに重点を置いています。 開始ページとエラー ページのサポートを可能にする、診断用の追加ミドルウェア コンポーネントが 1 つ用意されています。 OWIN が事実上のホスティング抽象化に成長するにつれて、Microsoft とサード パーティの両方によって開発されたミドルウェア コンポーネントのエコシステムも数が増えます。

まとめ

最初から、Katana プロジェクトの目標は、別の Web フレームワークを作成して、開発者に新たな学習を強制することではありません。 むしろ、.NET Web アプリケーション開発者に以前よりも多くの選択肢を与えるような抽象化を作成することが目標でした。 一般的な Web アプリケーション スタックの論理レイヤーを一連の置き換え可能なコンポーネントに分割することで、Katana プロジェクトを使用すると、スタック全体のコンポーネントを、それらのコンポーネントにとって意味のある速度で改善できます。 簡単な OWIN 抽象化に関するすべてのコンポーネントを構築することで、Katana は、フレームワークとその上に構築されたアプリケーションを、さまざまなサーバーやホスト間で移植できるようにします。 Katana は、開発者がスタックを制御できるようにすることで、開発者が自分の Web スタックの軽量性や機能の豊富さについて最終的な選択を行えるようにします。

Katana の詳細については、以下を参照してください。

確認