プロジェクト Katana の概要

作成者: ハワード・ディルキング

ASP.NET Framework は 10 年以上にわたり使用されており、このプラットフォームにより、数え切れないほどの Web サイトとサービスの開発が可能になりました。 Web アプリケーション開発戦略が進化するにつれて、フレームワークは、ASP.NET MVC や ASP.NET Web APIなどのテクノロジを使用して段階的に進化することができました。 Web アプリケーション開発がクラウド コンピューティングの世界に次の進化的なステップを踏むにつれて、プロジェクト Katana は、アプリケーションを ASP.NET するためのコンポーネントの基になるセットを提供し、柔軟で移植性が高く、軽量で、パフォーマンスを向上させることができます。別の方法として、プロジェクト Katana クラウドによって ASP.NET アプリケーションが最適化されます。

なぜカタナ – なぜ今?

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

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

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

歴史的モデルによって提起された課題

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

進化の手順: MVC と ASP.NET Web API ASP.NET

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

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

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

未来:機敏なフレームワーク

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

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

.NET 用 Open Web インターフェイス (OWIN)

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

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

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

IDictionary<string, object>

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

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

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

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

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

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

  • 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 プロジェクト コンポーネントによって使用されます。

Project Katana

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

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

Katana コンポーネントを使用したはじめに

それが最初に導入されたとき、人々の注目を集めた Node.js フレームワークの一つの側面は、Webサーバーを作成して実行できるシンプルさでした。 Katana の目標が Node.jsに照らして組み立てられていた場合、Katana は、開発者が Web アプリケーションの開発について知っているすべてを投げ出すことなく 、Node.js (およびフレームワークのようなフレームワーク) の多くの利点をもたらすと言って、それらを要約 ASP.NET 可能性があります。 このステートメントを true に保つには、Katana プロジェクトの使用を開始する際に、 を Node.jsするのと同様に単純である必要があります。

"Hello World!" の作成

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

[ASP.Net プロジェクト - WebApplication1] メニューのスクリーンショット。[作業の開始] ウィンドウ ウィンドウで 'Hello World' プロジェクトを作成する方法が示されています。選択するテンプレートが異なるウィンドウと、コア参照と単体テストを追加するためのオプションが表示されます。

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

install-package Microsoft.Owin.Host.SystemWeb

パッケージを Microsoft.Owin.Host.SystemWeb インストールすると、いくつかの追加パッケージが依存関係としてインストールされます。 これらの依存関係の 1 つは、 Microsoft.OwinOWIN アプリケーションを開発するためのいくつかのヘルパー型とメソッドを提供するライブラリです。 これらの型を使用して、次の "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

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

開発者コマンド Promt とブラウザー ウィンドウのスクリーンショット。コマンド ラインに入力されたコマンドと、Web ブラウザーでの 'Hello World' プロジェクトの外観の比較が示されています。

カタナのアーキテクチャ

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

アーキテクチャ レイヤーの図は、アプリケーションのアーキテクチャが分割されている論理レイヤーを示す 4 つのバーを示しています。

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 の type パラメーターとしてさらに指定されます。

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 サーバーを使用します)、規則を使用してユーザーのスタートアップ クラスを検索して実行します。 より詳細な制御を行う場合、実行可能ファイルには多数の追加のコマンド ライン パラメーターが用意されています。

開発者コマンド プロンプトのスクリーンショット。サーバー上でアプリケーションを実行する際のコマンド プロンプトのコード例を示しています。

サーバー

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

  • Microsoft.Owin.Host.SystemWeb: 前述したように、IIS と ASP.NET パイプラインはホストとサーバーの両方として機能します。 したがって、このホスティング オプションを選択すると、IIS はどちらも、プロセスのアクティブ化などのホスト レベルの懸念事項を管理し、HTTP 要求をリッスンします。 ASP.NET Web アプリケーションの場合は、ASP.NET パイプラインに要求を送信します。 Katana SystemWeb ホストは、httpModule と HttpHandler ASP.NET を登録して、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 つの引数を受け取ります。 このコンテキスト オブジェクトは、前に説明した NuGet パッケージによって Microsoft.Owin 提供され、要求、応答、環境ディクショナリへの厳密に型指定されたアクセスと、いくつかの追加のヘルパー型を提供します。

ミドルウェア クラスは、次のように、アプリケーションのスタートアップ コードで 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 パッケージ依存関係グラフは次のようになります。 (画像をクリックすると拡大表示されます。

コンポーネント - NuGet パッケージ階層の図。このイメージは、プロジェクト コンポーネントのフレームワークが接続され、NuGets のセットを介して配信されるライブラリ ツリーを示しています。

Katana プロジェクトのほぼすべてのパッケージは、直接または間接的に Owin パッケージに依存します。 これは IAppBuilder インターフェイスを含むパッケージであり、OWIN 仕様のセクション 4 で説明されているアプリケーション起動シーケンスの具体的な実装を提供します。 さらに、多くのパッケージは 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 の詳細については、以下を参照してください。

謝辞