ASP.NET

Katana プロジェクトの概要

Howard Dierking

ASP.NET が初めてリリースされた 2002 年当時の状況は今とは異なり、まだインターネットの揺籃期で、ユーザー数は約 5.69 億人、1 日の平均利用時間は約 46 分、Web サイトの数は約 300 万でしたが、わずか 10 年後の現在、インターネットのユーザー数は 22.7 億人、1 日の平均利用時間は 4 時間、Web サイトの数は 5.55 億に達しています (bit.ly/MY7GzO、英語)。

このような増加が、Web アプリケーションの構築と実行の基盤となるフレームワーク、ツール、ランタイムに対するアプリケーション開発者のニーズを急激に変化させたことは明らかです。最新の Web アプリは、迅速に変化できるように多種多様なコンポーネントやフレームワークを利用する必要があります。その上、クラウドのように大掛かりなランタイムで効率良く実行するにはフットプリントを小さくすることも必要です。

ASP.NET によって現在と将来のニーズを確実に満たせるようにすることが、Katana プロジェクトの中核をなす動機です。

Katana とは

Katana プロジェクトのきっかけを作ったのは、マイクロソフトではなく、Open Web Interface for .NET (OWIN) というオープン ソース プロジェクトです。OWIN では、Web サーバーとアプリケーション コンポーネント間の対話を定義する仕様を策定しています (owin.org、英語)。この仕様の目標は、Microsoft .NET Framework ベースの Web サーバーやアプリケーション コンポーネントの広大かつ多彩なエコシステムを刺激することなので、サーバーとアプリケーション間のすべての対話を少数の型と 1 つの関数シグネチャにまとめています。これをアプリケーション デリゲートまたは AppFunc と呼びます。

using AppFunc = Func<IDictionary<string, object>, Task>;

OWIN ベース アプリケーションでは、どのコンポーネントもアプリケーション デリゲートを 1 つサーバーに渡します。アプリケーション デリゲートを渡したコンポーネントは、次々と 1 つのパイプラインに連鎖されます。OWIN ベース サーバーはこのパイプラインに要求をプッシュします。リソースを効率的に使用するため、パイプライン内のすべてのコンポーネントが非同期に処理されます。アプリケーション デリゲートが Task オブジェクトを返すのはそのためです。

アプリケーションの状態、要求の状態、サーバーの状態など、すべての状態が、アプリケーション デリゲートで指定される IDictionary<string, object> オブジェクトに保持されます。環境ディクショナリと呼ばれるこのデータ構造は、要求がパイプラインを進んでいく過程で、コンポーネントからコンポーネントへと受け渡されます。環境ディクショナリにはキーと値の組み合わせであればどのようなデータでも挿入できますが、OWIN 仕様では、HTTP の主要要素のいくつかについてキーを定義しています (図 1 参照)

図 1 HTTP 要求に必須の環境ディクショナリ キー

 

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

多種多様なフレームワークやコンポーネントの作成者は、キーと値のペアの基本セットを環境ディクショナリに定義することで OWIN パイプラインでの相互運用が可能になります。ASP.NET MVC の HttpContextBase や ASP.NET Web API の HttpRequestMessage/HttpResponseMessage のように、特定の .NET オブジェクト モデルで相互運用方法の合意を強制する必要はありません。

アプリケーション デリゲートと環境ディクショナリという 2 つの要素が OWIN 仕様を形成しています。Katana プロジェクトは、マイクロソフトが作成、リリースした OWIN ベースのコンポーネントとフレームワークのセットです。

Katana の各コンポーネントのアーキテクチャ階層は図 2 のように表されます。


図 2 Katana プロジェクトのアーキテクチャ

階層を構成する各層は次のとおりです。

  • ホスト: アプリケーションを実行するプロセスです。IIS やスタンドアロンの実行可能ファイルから独自のカスタム プログラムまでがこれに該当します。ホストでは、起動、他の OWIN コンポーネントの読み込み、および適切な終了を行います。
  • サーバー: TCP ポートのバインド、環境ディクショナリの構築、および OWIN パイプライン全体の要求の処理を行います。
  • ミドルウェア: OWIN パイプラインの要求を処理するコンポーネントの総称です。単純な圧縮コンポーネントから、ASP.NET Web API などの完全なフレームワークまでさまざまですが、サーバーの観点からすると、単にアプリケーション デリゲートを公開するコンポーネントです。
  • アプリケーション: 開発するコードです。Katana は ASP.NET に置き換わるものではなく、新しい構成方法およびコンポーネントであるため、既存の ASP.NET Web API や SignalR アプリケーションは変更されず、これらのアプリケーションのフレームワークは OWIN パイプラインに参加できます。実際、この種のアプリケーションでは、Katana コンポーネントは小さな構成クラスとしてのみ確認できます。

Katana は、アーキテクチャ上、多くの場合にコードを再構築する必要なくこれらの各層を簡単に置き換えられるように考慮されています。HTTP 要求を処理する場合には、図 3 のデータ フローのような方法で各層が連動します。


図 3 Katana のデータ フローの例

Katana を使用して最新の Web アプリケーションをビルドする

最新の Web アプリケーションは、一般的に次の 4 つの機能を備えています。

  1. サーバー側でのマークアップ生成
  2. 静的ファイル サービスの提供
  3. AJAX 要求を処理する Web API
  4. リアルタイム メッセージング

これらの機能をすべて備えたアプリケーションをビルドするには、当該機能に適切に特化されたさまざまなフレームワークが必要です。ただし、そのようなフレームワークからアプリケーションを構成するのは困難で、現時点では IIS でアプリケーションのさまざまな部分をホストする必要があります。また、場合によっては、複数のアプリケーションと仮想ディレクトリを使用してアプリケーションの異なる部分を分離します。

一方、Katana を使用すると、さまざまな Web テクノロジから最新の Web アプリケーションを構成し、そのアプリケーションを希望する場所でホストし、単一の HTTP エンドポイントの下で公開できます。これにより、いくつかのメリットが得られます。

  • 機能別のアプリケーションではなく、1 つのアプリケーションにまとめられるため、配置が容易になる。
  • 認証などの機能を追加し、パイプラインの下流コンポーネントすべてに適用できる。
  • マイクロソフトとサード パーティのどちらのコンポーネントも、環境ディクショナリを介して同じ要求状態で実行できる。

ここからはサンプル アプリケーションについて説明します。このアプリケーションには、おなじみのバグ追跡の領域があります。アプリケーションではさまざまな状態 (バックログ、作業中、および完了) のバグを表示します。開発者は、このようなバグを各状態間で移動できます。また、複数の開発者が同時にバグに対応できるため、バグの状態が変わるとリアルタイムですべてのブラウザーが更新されます。アプリケーションのビルドでは、サーバー側でのマークアップ生成と静的ファイル サービスの提供に Nancy (nancyfx.org、英語)、AJAX 要求の処理に ASP.NET Web API (asp.net/web-api、英語)、リアルタイム メッセージング サービスに SignalR (signalr.net、英語) を使用します。

また、ブラウザー クライアント用のマークアップとスクリプトには時間をかけず、Knockout.js を使用して HTML マークアップと Web API と SignalR を分離します。

念頭に置く基本原則は、新しい機能が使用できるようになったらパイプラインに挿入するだけでその機能をアプリケーションに追加できるよう、これら異なるフレームワークすべてを 1 つの OWIN パイプラインに構成することです。

はじめに

Katana の目標の 1 つは、アプリケーションに追加した機能 (および各要求処理のパフォーマンス) を厳密に制御できるようにすることです。これを念頭に、まず Visual Studio 2013 Preview で新しい空の ASP.NET Web アプリケーションを作成します (図 4 参照)。


図 4 Visual Studio 2013 Preview の新しい ASP.NET Web アプリケーション プロジェクト

Web プロジェクト テンプレートは、空のテンプレートであっても、コンパイル済みのアセンブリを (他のプロジェクトの種類では一般的な) /bin/debug フォルダーではなく /bin フォルダーに配置するという便利な機能を既定で備えています。既定の Katana ホストは、この /bin フォルダーからアセンブリを探します。Katana ベース アプリケーションはクラス ライブラリとして作成できますが、プロジェクトのプロパティを変更してこの構造に従うか、異なるフォルダー構造のアセンブリと型を検索する独自のカスタム アプリケーション ローダーを用意する必要があります。

次に、Nancy Web フレームワークを使用してサーバー側のマークアップ生成コードをビルドします。

Nancy の構文は簡潔なため、HTTP ベースのサイトとサービスをすばやくビルドできます。この作業で重要なことは、ASP.NET Web API と同様、System.Web.dll への依存関係がなく、OWIN パイプラインで実行されるようにビルドすることです。ASP.NET MVC などのフレームワークは System.Web.dll への依存関係があり、IIS 以外でのホスティング シナリオにはあまり理想的ではありません。

ほとんどの場合、アプリケーションに新しい機能を追加するときは、まず NuGet パッケージを追加します (NuGet の詳細については docs.nuget.org (英語) を参照してください)。この記事の執筆時点では、ここで使用しているパッケージの多くがプレリリース版なので、NuGet ダイアログにリリース前のパッケージも表示されるようにしてください。

アプリケーションに Nancy を追加するには、単純に Nancy NuGet パッケージをインストールします。ただし、Nancy を OWIN パイプラインでも実行したいので、Nancy.Owin パッケージ (nuget.org/packages/nancy.owin、英語) をインストールします。これで、Nancy パッケージが依存関係としてインストールされ、OWIN パイプラインで Nancy を構成するための追加のヘルパー メソッドが提供されます。

次に、要求を処理する Nancy モジュール (モデル - ビュー - コントローラー (MVC) コントローラーに類似) と、ブラウザーに表示するビューを作成する必要があります。モジュールのコード (HomeModule.cs) は次のとおりです。

public class HomeModule : NancyModule
{
  public HomeModule() {
    Get["/"] = _ => {
      var model = new { title = "We've Got Issues..." };
      return View["home", model];
    };
  }
}

ご覧のとおり、モジュールではアプリケーションのルート ("/") に送られる要求を、関連するラムダで定義された匿名デリゲートによって処理するように宣言しています。この関数は、ページ タイトルを含むモデルを作成し、そのモデルをビューに渡して "home" ビューをレンダリングするよう Nancy に指示します。ビュー (図 5 参照) では、モデルの title プロパティをページの title 要素と h1 要素に挿入しています。

図 5 Home.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>@Model.title</title>
</head>
  <body>
    <header>
      <h1>@Model.title</h1>   
    </header>
    <section>
      <h2>Backlog</h2>
      <ul class="bugs" id="backlog">
        <li>a bug</li>
      </ul>
    </section>
    <section>
      <h2>Working</h2>
      <ul class="bugs" id="working">
        <li>a bug</li>
      </ul>
    </section>
    <section>
      <h2>Done</h2>
      <ul class="bugs" id="done">
        <li>a bug</li>
      </ul>
    </section>
  </body>
</html>

これらのリストの詳細については、Nancy のドキュメントを参照してください。

これで Nancy の基本機能を実装したので、OWIN パイプラインを確立し、このパイプラインに Nancy モジュールが参加するように構成します。そのためには、まず Katana のホスト コンポーネントとサーバー コンポーネントをインストールしてから、少量のプラミング コードを記述して OWIN パイプラインを設定し、そのパイプラインに Nancy を挿入する必要があります。

Katana のホスト コンポーネントとサーバー コンポーネントについては、IIS Express と System.Web を使用することから始めます。これらは Visual Studio によって本質的に認識され、アプリケーションのビルド中は快適な F5 操作が可能になります。System.Web ホストをプロジェクトに組み込むには、NuGet パッケージ Microsoft.Owin.Host.SystemWeb (bit.ly/19EZ2Rw、英語) をインストールします。

Katana の既定のコンポーネントは、スタートアップ クラスなど、OWIN アプリケーションの読み込みと実行にいくつかの異なる表記法を使用します。Katana ホストが OWIN アプリケーションを読み込むときは、次の規則 (優先度順に記載) に従ってスタートアップ クラスを検出、実行します。

  • web.config ファイルに key="owin:AppStartup" が設定された appSetting がある場合、ローダーはその設定値を使用する。値は有効な .NET 型の名前でなければならない。
  • アセンブリに属性 [assembly: OwinStartup(typeof(MyStartup))] が含まれる場合、ローダーは属性値で指定された型を使用する。
  • 上記の条件のどちらにも当てはまらない場合、ローダーは読み込んだアセンブリをスキャンし、シグネチャ void Configure(IAppBuilder app) に一致するメソッドが設定された Startup という名前の型を探す。

この例の場合、ローダーがアセンブリをスキャンしてクラスを探せるようにします。ただし、プロジェクトに多くの異なる型やアセンブリがある場合、appSetting またはアセンブリ属性を利用して不要なスキャンを行わないようにすることをお勧めします。

OWIN パイプラインを初期化するスタートアップ クラスを作成し、Nancy をパイプライン コンポーネントとして追加します。Startup という新しいクラスを作成し、次の構成メソッドを追加します。

public class Startup
{
  public void Configuration(IAppBuilder app)
  {
    app.UseNancy();
  }
}

UseNancy は、Nancy.Owin NuGet パッケージにより使用可能になった拡張メソッドです。IAppBuilder の汎用 Use メソッドを使用してミドルウェアを追加することもできますが、構成プロセスを簡略化するそのような便利な拡張メソッドが多くのミドルウェア ライブラリで提供されています。

この時点で、Visual Studio で F5 キーを使用してプロジェクトを実行すると、まだそれほど魅力的ではありませんが、十分機能する Web アプリケーションになっていることを確認できます。この時点の OWIN パイプラインは 1 つのコンポーネント (Nancy) から構成されています (図 6 参照)。


図 6 1 つのコンポーネントによる機能する Web アプリケーション

ASP.NET Web API を使用してデータを組み込む

現在、HTML ビューは主に静的なマークアップから構成されています。ここで、対応が必要な実際のバグをいくつかユーザーに表示します。多くの最新 Web アプリケーションでは、データをブラウザー クライアントに送信するタスクは、サーバー側のマークアップ生成フレームワーク (Nancy など) から個別の Web API サービスに移ってきています。ブラウザーは、HTML ページを読み込み、即座に JavaScript を実行します。JavaScript は、Web API からデータをフェッチし、ページ内で動的に HTML マークアップを作成します。

ASP.NET Web API フレームワークを使用して Web API を構築することから始めます。これまでどおり、まず Web API NuGet パッケージをインストールします。ASP.NET Web API を簡単に OWIN パイプラインに挿入できるように、Microsoft.AspNet.WebApi.Owin パッケージ (bit.ly/1dnocmK、英語) をインストールします。このパッケージにより、残りの ASP.NET Web API フレームワークが依存関係としてインストールされます。フレームワークのインストール後、図 7 の単純な API を作成します。

図 7 BugsController.cs

public class BugsController : ApiController
{
  IBugsRepository _bugsRepository = new BugsRepository();
  public IEnumerable<Bug> Get()
  {
    return _bugsRepository.GetBugs();
  }
  [HttpPost("api/bugs/backlog")]
  public Bug MoveToBacklog([FromBody] int id)
  {
    var bug = _bugsRepository.GetBugs().First(b=>b.id==id);
    bug.state = "backlog";
    return bug;
  }
  [HttpPost("api/bugs/working")]
  public Bug MoveToWorking([FromBody] int id)
  {
    var bug = _bugsRepository.GetBugs().First(b => b.id == id);
    bug.state = "working";
    return bug;
  }
  [HttpPost("api/bugs/done")]
  public Bug MoveToDone([FromBody] int id)
  {
    var bug = _bugsRepository.GetBugs().First(b => b.id == id);
    bug.state = "done";
    return bug;
  }
}

API には、リポジトリから一連のバグ オブジェクトを返すメソッドや、バグを別の状態に移行するメソッドが含まれます。ASP.NET Web API の詳細については、asp.net/web-api (英語) を参照してください。

ASP.NET Web API コントローラーを定義したので、これを既存の OWIN パイプラインに追加する必要があります。それには、スタートアップ クラスの Configuration メソッドに次の行を追加するだけです。

var config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute("bugs", "api/{Controller}");
app.UseWebApi(config);

Nancy と同様、ASP.NET Web API OWIN パッケージでは、UseWebApi 拡張メソッドが提供されており、ASP.NET Web API を既存の OWIN パイプラインに簡単に組み込めます。これで、OWIN パイプラインは 2 つのコンポーネント (ASP.NET Web API と Nancy) から構成されるようになります (図 8 参照)。


図 8 2 つのコンポーネントによる OWIN パイプライン

パイプラインに要求が送られ、その要求が ASP.NET Web API のルーティング規則のいずれかに一致している場合は、ASP.NET Web API で要求が処理され応答が生成されます。一致しなければ、要求はパイプラインを進み、Nancy による処理が試みられます。パイプラインのどのコンポーネントでも特定の要求を処理できなければ、Katana の既定のコンポーネントにより HTTP 404 応答が返されます。

ASP.NET Web API は機能しますが、まだ home ビューからこの API にアクセスできません。そのため、Web API からのデータを使用して各状態 (バックログ、作業中、および完了) のバグのリストを生成するコードを追加します。このタスクには、JavaScript の モデル - ビュー - ビューモデル (MVVM) ライブラリである、Knockout.js を利用します。Knockout の詳細については knockoutjs.com (英語) を参照してください。

Knockout を使用した HTML マークアップの動的生成をクライアント側で行うには、まず、ASP.NET Web API からすべてのバグを取得して、Knockout を使用して HTML 要素をバインドできるビューモデルを作成する必要があります。これを図 9 に示します。

図 9 Bugs ビューモデルの設定

<script>
  $(function () {
    var viewModel;
    $.getJSON('/api/bugs', function(data) {
      var model = data;
      viewModel = {
        backlog: ko.observableArray(
          model.filter(function(element) { return element.state === 'backlog'; })),
        working: ko.observableArray(
          model.filter(function(element) { return element.state === 'working'; })),
        done: ko.observableArray(
          model.filter(function(element) { return element.state === 'done'; })),
        changeState: function (bug, newState) {
          var self = this;
          $.post('/api/bugs/' + newState, { '': bug.id }, function(data){
            self.moveBug(data);
          });
        },
        moveBug: function (bug) {
          // Remove the item from one of the existing lists
          ...
          // Add bug to correct list
          this[bug.state].push(bug);
        }
      };
      ko.applyBindings(viewModel);
    })
  })
</script>

ビューモデルを作成すると、Knockout は、Knockout 特有の属性で修飾された HTML 要素にビューモデルをバインドすることで、HTML コンテンツを動的に生成して更新できるようになります。たとえば、バックログのリストは、図 10 に示す属性を使用してビューモデルから生成できます。

図 10 バックログ リスト生成用の属性

<section>
  <h2>Backlog</h2>
  <ul class="bugs" id="backlog" data-bind="foreach:backlog">
    <li>
      [<span data-bind="text: id"></span>] <span data-bind="text: title"></span>:
        <span data-bind="text: description"></span>
      <ul>
        <li><a href="#" data-bind="click: $root.changeState.bind($root, $data,
          'working')">Move to working</a></li>   
        <li><a href="#" data-bind="click: $root.changeState.bind($root, $data,
          'done')">Move to done</a></li>   
      </ul>
    </li>
  </ul>
</section>

SignalR を使用したリアルタイムの変更通知を追加する

この時点で、単一のページとして完全に機能する Web アプリケーションができました。ユーザーは home ビューの閲覧とバグの状態移行が可能になります。さらに、現在レベルの機能の基盤になっているテクノロジ (Nancy と ASP.NET Web API) は同じ OWIN パイプラインで一緒に実行されています。

しかし、もう 1 歩進めて、あるユーザーによって行われたバグの更新を他のユーザーがリアルタイムに確認できるようにします。そのために SignalR ライブラリを使用します。このライブラリからは、ブラウザーと Web サーバー間のリアルタイム メッセージ交換を管理するクライアント API とサーバー API の両方が提供されます。SignalR も OWIN パイプラインで実行されるように記述されているため、既存のアプリケーションへの追加は簡単です。

Hub という SignalR 機能を使用します。SignalR の詳細についてはここでは説明しませんが、Hub を使用することで、クライアントとサーバーが互いにメソッドを呼び出すことができます (SignalR の概要については bit.ly/14WIx1t (英語) を参照してください)。アプリケーションでは、ASP.NET Web API がバグの状態変更の要求を受け取ると、API によりバグが更新され、更新されたバグが SignalR Hub を通じて現在アプリケーションに接続しているすべてのブラウザー クライアントにブロードキャストされます。

このプロセスは、Hub をサーバー上に作成することから始めます。SignalR のその他の機能は使用しないため、Hub は単純に次の空のクラス定義で構成します。

[HubName("bugs")]
public class BugHub : Hub
{
}

ASP.NET Web API から Hub にブロードキャストを送信するため、まず、インスタンスをそのランタイム コンテキストに移動する必要があります。次の BugsController コンストラクターを追加するとこの移動を実現できます。

public BugsController()
{
  _hub = GlobalHost.ConnectionManager.GetHubContext<BugHub>();
}

いずれかの MoveToXX アクションから、接続中のすべてのブラウザー クライアントに更新されたバグをブロードキャストできます。

_hub.Clients.All.moved(bug);

home ビューでは、次のようにして SignalR JavaScript ライブラリへのいくつかのスクリプト参照を追加した後、bugsHub に接続して "moved" メッセージのリッスンを開始できます。

$.connection.hub.logging = true;
var bugsHub = $.connection.bugs;
bugsHub.client.moved = function (item) {
  viewModel.moveBug(item);
};
$.connection.hub.start().done(function() {
  console.log('hub connection open');
});

moved 関数を通じてサーバーから呼び出しを受け取るときに、項目のクリック ハンドラーと同じ方法で viewModel moveBug メソッドを呼び出しているのがわかります。このメソッドは SignalR のブロードキャストの結果として実行されるため、すべてのブラウザーで同時にビューモデルを更新できるところに違いがあります。これは、ブラウザー ウィンドウを 2 つ開き、片方で変更を行い、もう片方で状態の変化を確認するとはっきりとわかります。

前に述べたように、SignalR を OWIN パイプラインに追加するのは簡単です。次の行をスタートアップ クラスの Configuration メソッドに追加するだけです。

app.MapSignalR();

これで、図 11 に示すようなパイプラインが作成されます。


図 11 3 つのコンポーネントによる OWIN パイプライン

自己ホストに移行する

まだ備えていない重要な機能もありますが、興味深いいくつかの処理が可能な機能するバグ管理アプリケーションになりました。マイクロソフトとサードパーティ両方の Katana ミドルウェア コンポーネントを使用して、アプリケーションに徐々に機能を追加してきましたが、これらの多くは、ASP.NET HttpModules と HttpHandlers を使用すれば既に実現可能でした。では、ここで本当に実現されたのは、パイプライン コンポーネントを構成する単純なコード駆動のアプローチ以外に何があるでしょうか。

図 2 に示した、高レベルの Katana アーキテクチャを思い出してください。ここまでは、Katana 階層の上位 2 層で作業していたにすぎません。しかし、これらの層は、サーバーとホストを含め、すべて簡単に置き換えが可能です。

これを示すには、パイプライン全体を取り出して IIS と System.Web.dll から分離し、OwinHost.exe という Katana 実行可能ファイルによりホストされる単純で軽量の HTTP サーバーの上に置きます。開発コンピューターに Web サーバーがインストールされていない設定から、プロセス分離を使用して Web サーバーにアクセスを公開しない共有ホスティング環境にアプリケーションが配置されている運用環境まで、自己ホストはさまざまなシナリオで役立つことがわかります。

次の追加 NuGet パッケージをインストールすることから始めます。

次に、アプリケーションをリビルドします。新しいサーバーとホスト上でアプリケーションを実行する場合リビルドは必要ありません。要件は、これらのファイルが実行時に /bin フォルダーに存在することだけです。リビルドは /bin フォルダーにファイルをコピーするのに便利な方法です。

パッケージのインストールとファイルのコピーの後、コマンド プロンプトを開き、Web プロジェクトのルート フォルダーに移動してパッケージ フォルダーから OwinHost.exe を呼び出します (図 12 参照)。

> ..\packages\OwinHost.2.0.0\tools\OwinHost.exe


図 12 packages フォルダーから OwinHost.exe を呼び出す

既定で、OwinHost.exe が起動され、Microsoft.Ow­in.Host.HttpListener サーバーが読み込まれ、ポート 5000 のリッスンが開始されます。その後、http://localhost:5000 に移動し、アプリケーション全体が実行されているのを確認できます。

さらに、コマンドライン スイッチを使用して、既定値のほぼすべてを上書きできます。たとえば、別のポートをリッスンする場合は、-p 12345 と入力します。まったく別のサーバーを使用する場合は、-s <カスタム サーバー アセンブリ> を使用します。Katana 設計の真価は、モジュール性にあります。階層のどこかが新しくなると、実行中のアプリケーションに即座に統合できます。階層のすべてのコンポーネント間のコントラクトはアプリケーション デリゲートにすぎないので、革新の速度は現在よりも速くなります。

始まったばかり

Visual Studio 2013 と同時に Katana 2.0 がリリースされます。新しいリリースでは、次の 2 つの主要分野に重点が置かれています。

  • 自己ホスト用の中核的なインフラストラクチャ コンポーネントの提供
  • Facebook、Google、Twitter、Microsoft アカウントなどのソーシャル プロバイダー、および Windows Azure Active Directory、cookie、フェデレーションなどのプロバイダー用の認証向けの豊富なミドルウェアの提供

Katana 2.0 のリリース後は、作業はすぐに次期 Katana コンポーネントに移ります。その詳細と優先順位はまだ取り決め中ですが、katanaproject.codeplex.com (英語) で問題を報告することでその決定に影響を与えることができます。最後になりますが、この記事のコードはすべて bit.ly/1alOF4m (英語) で参照できます。


Howard Dierking は Windows Azure フレームワークとツール チームのプログラム マネージャーを務めており、ASP.NET、NuGet、および Web API に重点的に取り組んでいます。以前には、MSDN マガジンの編集長の経験や、Microsoft Learning のデベロッパー認定プログラムを指揮したことがあります。Microsoft に勤務する前は、分散システム専門の開発者兼アプリケーション アーキテクトとして 10 年間仕事に取り組んでいました。

この記事のレビューに協力してくれた技術スタッフの Brady Gaster と Scott Hanselman に心より感謝いたします。