しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

ASP.NET vNext で追加された新しい HTTP 抽象化クラス

ASP.NET vNext ではこれまで System.Web.dll で提供されていた、古く巨大になった HttpContext などを捨てて、新しい軽量かつモジュラーな HTTP 抽象化クラスを提供しています。

GitHub - aspnet/HttpAbstractions: [Archived] HTTP abstractions such as HttpRequest, HttpResponse, and HttpContext, as well as common web utilities. Project moved to https://github.com/aspnet/AspNetCore

これまでの HttpContext を使っていた人は、まず最初に HttpContext.Current プロパティが無いことに驚くかもしれません。ASP.NET vNext では HttpContext は MVC や Web API であれば Controller から取れますし、Razor にも Context プロパティが用意されているので、基本的にクラスライブラリなどで HttpContext.Current を使っていない限りは問題ないかと思います。

ある程度はプロパティ名などに互換性がありますが、期待しすぎるのは良くありません。しかし NameValueCollection などの古いコレクションではなくジェネリックなコレクションのみで実装されているので、とても扱いやすいクラスとなっています。

どちらかと言えば System.Web よりも Katana に実装は近いです。

/// <summary>
/// Gets or set the owin.RequestPathBase.
/// </summary>
/// <returns>The owin.RequestPathBase.</returns>
public abstract PathString PathBase { get; set; }


/// <summary>
/// Gets or set the request path from owin.RequestPath.
/// </summary>
/// <returns>The request path from owin.RequestPath.</returns>
public abstract PathString Path { get; set; }
https://github.com/aspnet/HttpAbstractions/blob/dev/src/Microsoft.AspNet.Http/HttpRequest.cs

XML ドキュメントコメントには OWIN 周りの記述が残っていることから、vNext の HTTP 抽象化クラスのインターフェースは OWIN つまり Katana 由来だということです。

Katana 由来と言っても普通に MVC 6 などで使う場合には、Intellisense でメソッド名を見るだけで理解できる命名になっているので問題なさそうです。これまでの小難しい経緯など理解する必要もないので、これまで MVC 5 を使っていた人でもすぐに慣れるかと思います。

おまけ

しかし内部実装は全く異なっています。もう少し見ていきたいので、まずは HttpAbstractions リポジトリに用意されているプロジェクトの構造から見ていきます。

  • Microsoft.AspNet.FeatureModel
  • Microsoft.AspNet.Http.Extensions
  • Microsoft.AspNet.Http
  • Microsoft.AspNet.HttpFeature
  • Microsoft.AspNet.Owin
  • Microsoft.AspNet.PipelineCore
  • Microsoft.AspNet.WebUtilities

色々ありますが、重要なのは FeatureModel / Http / HttpFeature / PipelineCore となります。後は OWIN との互換性用だったりユーティリティクラスとかです。

大雑把に解説すると以下のような感じです。

  • FeatureModel
    • Feature をラップするクラスとコレクションを提供
  • Http
    • HttpContext などの抽象クラスを提供
  • HttpFeature
    • 各 Feature のインターフェースを提供
  • PipelineCore
    • 実際に HttpContext や各 Feature を実装しているプロジェクト

新しい HttpContext / HttpRequest / HttpResponse といったクラスは ***Feature という機能単位で実装されたクラスと、I***Feature という Assembly Neutral なインターフェースを組み合わせて作られています。*1

それぞれの Feature は HttpContext.SetFeature メソッドを呼び出すことでオーバーライドが可能ですが、それら Feature を利用するために新しく導入されたのが Microsoft.AspNet.FeatureModel です。

https://github.com/aspnet/HttpAbstractions/tree/dev/src/Microsoft.AspNet.FeatureModel

基本的には DI と同じような考え方ですが Assembly Neutral なインターフェースを使うためなのか、Type クラスの他に名前ベースでも対象となるインスタンスを解決できるようになっています。

ちなみに中身はほぼ以下のクラス、インターフェースのみです。

  • FeatureCollection
  • FeatureObject
  • IFeatureCollection

FeatureCollection はリビジョンを持っていて、PipelineCore にある FeatureReference を使うことで常に最新の Feature を参照出来る面白い仕組みだったりするんですが、長くなってきたのでまた別の機会で。

*1:ASP.NET vNext と OWIN のインターフェースをさらに抽象化するために Feature を作ったという感じ