web-dev-qa-db-ja.com

AddMvcCore()を使用して「純粋な」ASP.NET Core Web APIを実装する方法

AddMvc()を使用することは、サービスを制御するための優れたオプションであることに気づかずに、デフォルトのAddMvcCore()サービスを使用する多くのASP.NET Core Web APIプロジェクトを見てきました。

AddMvcCore()なぜそれが優れているのですか?を使用して、ASP.NET Core Web APIを正確に実装する方法

33
Svek

AddMvc()AddMvcCore()の違いは何ですか?

最初に理解しておくべき重要なことは、AddMvc()AddMvcCore()のプリロードバージョンにすぎないということです。 AddMvc()拡張の正確な実装は、 GitHubリポジトリ で確認できます。

私は次の人と同じくらいデフォルトのVSテンプレートを使うのが好きですが、時にはそれが間違った選択であるときを知る必要があります。私は、これらのデフォルトのサービスを単に「元に戻す」ことを目的とするのではなく、これらのデフォルトのサービスを「元に戻す」試みに傾いている複数のガイドをオンラインで見ました。

オープンソースであるASP.NET Coreの出現により、「魔法」を失うことを恐れずにレイヤーを剥がして下位レベルで作業することができない理由は、実際にはありません。


「最小」と「純粋」の定義

注:定義は、この回答のコンテキストのみを対象としています。主にわかりやすくするためと理解を深めるためです。

この答えは、「最小」ではなく「純粋」に傾いています。理由を説明したいので、私が話していることはより明確です。

最小。「最小」ソリューションは、を呼び出しさえしない実装ですAddMvcCore()method at all。この理由は、MVCは実際には、独自のWeb APIをアセンブルするための「必須」コンポーネントではなく、追加の依存関係によりコードにある程度の重みが確実に追加されるためです。このシナリオでは、AddMvcCore()メソッドを使用していないため、ここにアプリケーションに挿入することもありません。ここでは

_public void Configure(IApplicationBuilder app)
{
    app.UseMvc(); // you don't need this
}
_

これは、独自のルートをマッピングし、独自の方法でcontextに応答することを意味します。これは実際にはまったく難しいことではありませんが、トピックから外れているため、飛び込みたくはありませんが、最小限の実装の小さな味です

_public void Configure(IApplicationBuilder app)
{
    app.Map("/api", HandleMapApi);
    // notice how we don't have app.UseMvc()?
}    

private static void HandleMapApi(IApplicationBuilder app)
{
    app.Run(async context =>
    {
        // implement your own response
        await context.Response.WriteAsync("Hello WebAPI!");
    });
}
_

多くのプロジェクトにとって、「最小限の」アプローチとは、MVCにある機能の一部を放棄することを意味します。設計パターン、利便性、保守性、コードフットプリント、そして最も重要なパフォーマンスとレイテンシのバランスが取れているため、オプションを比較検討し、この設計パスが正しい選択かどうかを確認する必要があります。 簡単に言うと、「最小限の」ソリューションとは、コードとリクエストの間のサービスとミドルウェアを最小限に抑えることを意味します。

Pure。「純粋な」解決策(この回答の文脈に関する限り)は、「事前バンドル」されるすべてのデフォルトのサービスとミドルウェアを避けることです。 "AddMvc()を最初に実装しないことで。代わりに、次のセクションでさらに説明するAddMvcCore()を使用します。


AddMvcCore()を使用して独自のサービス/ミドルウェアを実装する

最初に始めることは、ConfigureServicesAddMvcCore()を使用するようにセットアップすることです。 GitHubリポジトリ を見ると、AddMvc()が標準のサービス/ミドルウェアのセットでAddMvcCore()を呼び出していることがわかります。

「不要」として際立っているサービス/ミドルウェアの一部を次に示します。

_var builder = services.AddMvcCore();

builder.AddViews();
builder.AddRazorViewEngine();
builder.AddRazorPages();
_

これらのデフォルトサービスの多くは、一般的なWebプロジェクトには適していますが、通常は「純粋な」Web APIには望ましくありません。

以下は、Web APIにAddMvcCore()を使用したConfigureServicesのサンプル実装です。

_public void ConfigureServices(IServiceCollection services)
{
    // Build a customized MVC implementation, without using the default AddMvc(),
    // instead use AddMvcCore(). The repository link is below:
    // https://github.com/aspnet/Mvc/blob/release/2.2/src/Microsoft.AspNetCore.Mvc/MvcServiceCollectionExtensions.cs

    services
        .AddMvcCore(options =>
        {
            options.RequireHttpsPermanent = true; // this does not affect api requests
            options.RespectBrowserAcceptHeader = true; // false by default
            //options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();

            // these two are here to show you where to include custom formatters
            options.OutputFormatters.Add(new CustomOutputFormatter());
            options.InputFormatters.Add(new CustomInputFormatter());
        })
        //.AddApiExplorer()
        //.AddAuthorization()
        .AddFormatterMappings()
        //.AddCacheTagHelper()
        //.AddDataAnnotations()
        //.AddCors()
        .AddJsonFormatters();
}
_

上記の実装は、ほとんどAddMvc()拡張メソッドの複製ですが、他の人がこれを行うことの追加の利点を確認できるように、いくつかの新しい領域を追加しました。

  • カスタム入力/出力フォーマッタこれは、JSONを使用する代わりに、高度に最適化された独自のシリアライザ(Protobuf、Thrift、Avroなど)を実行できる場所です。 (またはさらに悪いXML)シリアル化。
  • リクエストヘッダーの処理。Acceptヘッダーが認識されるかどうかを確認できます。
  • 認証処理。独自のカスタム認証を実装したり、組み込み機能を利用したりできます。
  • ApiExplorer。一部のプロジェクトでは、それを含めることができます。
  • Cross-Origin Requests(CORS)。WebAPIでより緩和されたセキュリティが必要な場合は、有効にすることができます。

「純粋な」ソリューションのこの例があれば、AddMvcCore()を使用する利点がわかり、快適に使用できます。

ASP.NET CoreのWebホスト上での作業中にパフォーマンスと遅延を制御することに真剣に取り組んでいる場合、「最小限の」ソリューションを深く掘り下げて、要求パイプラインのエッジで対処するのではなく、 MVCミドルウェアによって動きが取れなくなります。


追加の読書

ミドルウェアパイプラインがどのように見えるかを視覚的に見てください...私の定義では、レイヤーが少ないということは「最小限」を意味しますが、「純粋」はMVCのクリーンバージョンにすぎません。

enter image description here

詳細については、Microsoftのドキュメントをご覧ください。 ASP.NET Core Middleware Fundamentals

75
Svek