AS.NET Core 2.2におけるEndpointルートの詳細


Entdpointルート
ASP.NET Core 2.2に、Endpoint(エンドポイント)ルートというルートが追加されました。本論文では、従来のルーティングシステムを従来のルーティングと呼ぶ。
本文はソースの方式を通して、伝統的なルートとEntpointルートの一部の核心機能と実現方法を紹介します。
ASP.NET Core 2.2にアップグレードすると、自動的にEndpointルートが有効になります。従来の実装ロジックを復元するには、以下のコードを追加する必要があります。

services.AddMvc(options => options.EnableEndpointRouting = false)
  .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
本論文で分析したソースコードはASP.NET Core 2.2.3バージョンのソースコードに基づいている。
Entdpoint作用
Endpointルーティングと従来のルーティングの違いは、従来のルートUrlとActionの対応関係の処理がUseMvcで行われていることである。私たちはUrlによって対応するアクションを取得して処理することができません。
Endpointとは、UrlとActionのマッピング関係をMvcから取り外し、独立して使うミドルウェアです。
これによってもたらされる利点は、他のミドルウェアにおいて、Controllerとアクションに関するいくつかの情報を使用することができます。
フレームもLinkGenerator類を提供して、直接にEndpointによってリンクを生成して、HttpConteetの情報を必要としません。
また、いくつかのRPS(Requests per Second)も向上した。
しかし、現在のEndpointは依然としてUseMvcで呼び出されており、より多くの開放的な使い方はASP.NET Core 3.0で実現されます。
Endpointルートを有効にする
ソースコードはGithubを参照してください。ソースコードを取得してローカルに見ることもできます。
MvcAppliation Burder Extensions.csファイル72行のUseMvc方法では、以下のコードが見られます。

var options = app.ApplicationServices.GetRequiredService<IOptions<MvcOptions>>();

if (options.Value.EnableEndpointRouting)
{
  ...
}
else
{
  ...
}

ifの中はEntdpointルーティングの論理であり、elseは伝統的なルーティングの論理である。
MvcOptionsの構造方法は以下のように示しています。EnbaleEntpointRoutingはComptibilitySwitchによってデフォルト値を制御しています。これはComptibility Verssion.Verssion_です。2_2 Endpointルートを有効にする理由。

public MvcOptions()
{
  // ...
  _enableEndpointRouting = new CompatibilitySwitch<bool>(nameof(EnableEndpointRouting));
  // ...
}
Entdpointルーティング実現原理
MvcApplection Burder Extensions.csファイルの92-123行のコードは、すべてのControllerの中のアクションをEndpointに変換するものです。
129行のUseendpoint Routingには、EndpointRoutingMiddlewareの中間部品が追加されています。この中間部品は、すべてのEndpointの中から現在のルーティング対応のEndpointを見つけて、Featureのセットに入れます。
132行のUseEntindpointにEndpointMiddlewareのミドルウェアを追加しました。このミドルウェアはEndpointRoutingMiddlewareで見つけたEnd pointを取り出し、その中のMetaData情報に基づいて対応するControllerとActを見つけて呼び出します。
UseMvc方法では、UseEndpointRoutingとUseEndpointは連続した二つの中間部品であり、UseEndpointは要求の終了であり、これは私達がカスタマイズした中間部品がEndpoint情報を取得できないことを意味しています。
しかし、手動でUseEndpointを呼び出すことで、私たちはまだEndpointのルート情報を得ることができます。
使用例
使用例を以下に示す。
LogAttributeクラスを定義し、Message属性を含み、アクション上で使用を宣言します。
EndpointTest Middlewareのミドルウェアを定義し、LogAttributeのMessage属性を出力します。
UseendpointRoutingを手動で呼び出して、私達が定義したEndpoint TestMiddlewareの中間部品を呼び出します。

// Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
  app.UseEndpointRouting();

  app.UseMiddleware<EndpointTestMiddleware>();

  app.UseMvc(routes =>
  {
    routes.MapRoute(
      name: "default",
      template: "{controller=Home}/{action=Index}/{id?}");
  });
}
// EndpointTestMiddleware.cs
public class EndpointTestMiddleware
{
  private RequestDelegate _next;

  public EndpointTestMiddleware(RequestDelegate next)
  {
    _next = next;
  }

  public async Task Invoke(HttpContext httpContext)
  {
    var endpoint = httpContext.Features.Get<IEndpointFeature>()?.Endpoint;
    if (endpoint == null)
    {
      await _next(httpContext);
      return;
    }
    var attruibutes = endpoint.Metadata.OfType<LogAttribute>();
    foreach (var attribute in attruibutes)
    {
      Debug.WriteLine("------------------------------------------------------------------------");
      Debug.WriteLine(attribute.Message);
      Debug.WriteLine("------------------------------------------------------------------------");
    }
    await _next(httpContext);
  }
}
// LogAttribute.cs
[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)]
public sealed class LogAttribute : Attribute
{
  public LogAttribute(string message)
  {
    Message = message;
  }

  public string Message { get; set; }
}
// HomeController.cs
public class HomeController : Controller
{
  [Log("Index")]
  public IActionResult Index()
  {
    return View();
  }

  [Log("Privacy")]
  public IActionResult Privacy()
  {
    return View();
  }
}

このようにすれば、私たちは自分たちのミドルウェアの中からEndpointの情報を入手し、その後、Controller上のLogAttributeを見つけてからMessageを出力することができます。
締め括りをつける
EndpointはASP.NET Core 2.2の新しいルート機構であり、伝統的なルートの拡張が困難な問題を解決し、伝統的なルートとMVCの結合が過剰である問題を解決し、RPSを向上させました。
この論文では、Endpointルーティングを紹介し、Endpointの実現原理を簡単に分析し、使用例を示した。
参照リンク:
https://devblogs.microsoft.com/aspnet/asp-net-core-2-2-0-preview1-endpoint-routing/
https://www.stevejgordon.co.uk/asp-net-core-first-look-at-global-routing-dispatcher
https://rolandguijt.com/endpoint-routing-in-asp-net-core-2-2-explained/
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。