つばろぐ

主に C#, .NET, Azure の備忘録です。たまに日記。

ASP.NET CoreのMiddlewareで依存関係を解決する方法

ASP.NET Core 2.xの内容です。1.xについては未検証。

ASP.NET Coreでは依存関係(Dependency Injection / DI)の取扱いがすごく簡単になっています。
なのでMiddlewareでもDIを使いたい場面がでてきます。例えばロガーとか。

Middlewareについての説明は省略しますので、公式ドキュメントを参照してください。

docs.microsoft.com

HTTPリクエスト/レスポンスの流れのなかに処理を差し込むパイプラインが用意されているイメージです。

pipeline

Middlewareでの依存関係の解決方法

ざっくりいうと .NET Coreでの依存関係解決は「コンストラクタ引数に使用したいオブジェクトを指定する」という方法になります。
ControllerやService、Repositoryなんかを使う方はイメージしやすいかと思います。
Middlewareも例に漏れず同じ方法になります。

この記事で詳細な説明をしますがサンプルコードが見たい方はこちらをどうぞ。

github.com

こんなMiddlewareが登録されていたとする

Startup.cs (該当箇所のみ記載)

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.UseMiddleware<MyMiddleware>();
    }
}

Startup.cs でMiddlewareを登録する際は、特にDIコンテナー内のオブジェクトは指定しません。

素の状態のMiddleware

MyMiddleware.cs
nextという変数はMiddlewareのルールとして必要なオブジェクトになります。

public class MyMiddleware
{
    private readonly RequestDelegate next;

    public MyMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        await next(context);
    }
}

コンストラクタ引数で依存関係を解決する

MyMiddleware.cs にロガーを取り出す処理を実装してみます。
Middlewareのコンストラクタ引数にロガーを指定するだけで済みます。
取り出したロガーは readonly なフィールド変数として保管しておくと他のメソッドで利用することができます。

public class MyMiddleware
{
    private readonly RequestDelegate next;
    private readonly ILogger<MyMiddleware> logger;

    public MyMiddleware(RequestDelegate next, ILogger<MyMiddleware> logger)
    {
        this.next = next;
        this.logger = logger;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        logger.LogInformation($"QueryString: {context.Request.QueryString}");
        await next(context);
    }
}

要求ごとに依存関係を解決する

Startup.cs で何かしらのオブジェクトをDIに登録する際に、有効期間を1要求ごと( AddScoped )にしている場合、Middlewareではコンストラクタ引数で依存関係を解決するのではなく、要求ごとに依存関係を解決する必要があります。

docs.microsoft.com

ミドルウェアでスコープ サービスを使用している場合、サービスを Invoke または InvokeAsync メソッドに追加します。 コンストラクターを使用して挿入すると、サービスがシングルトンのように動作するよう強制されるので、コンストラクターを使用した挿入は行わないでください。 詳細については、「ASP.NET Core のミドルウェア」を参照してください。

Startup.cs の例 (該当箇所のみ記載)

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddScoped<IMyService, MyService>();
    }
}

MyMiddleware.cs

「要求ごとに依存関係を解決する」とはどういうことかというと、ミドルウェアパイプライン上で呼び出されるごとということなので、 InvokeAsync メソッドに引数を追加することで依存関係を解決します。

public class MyMiddleware
{
    private readonly RequestDelegate next;

    public MyMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task InvokeAsync(HttpContext context, IMyService myService)
    {
        string message = myService.Say("tsubakimoto");
        await next(context);
    }
}

PHPカンファレンス福岡2019の実行委員長を務めることになりました&スポンサー募集のお願い #phpconfuk

PHPカンファレンス福岡2019の実行委員長を務めることになりました

phpcon.fukuoka.jp

私を知っている方々はC#erのイメージが強いかと思いますが、PHPも使ったりします。
昨年のカンファレンスの懇親会のときに、2018年の実行委員長と2015年の実行委員長から任命していただきました。

私も2016年のカンファレンスからスタッフとして関わっており、2016年には登壇もしている思い入れの強いイベントです。

tsubalog.hatenablog.com

www.youtube.com

PHPカンファレンス福岡自体、PHPネタオンリーではなく「PHPerが気になる・PHPerに聞いてほしい」テーマであればなんでもOKみたいな感じです。
例年、PHP以外のプログラミング言語フレームワークのセッションなんかも採択されています。

PHPカンファレンス福岡のイベント運営は、とても丁寧で準備に時間をかけて、参加者やスピーカー、スポンサーにカンファレンスを楽しんでもらおうという意識を感じる、控えめに言って素晴らしいです。
スタッフしながらでもとても学びになります。

そんなPHPカンファレンス福岡の今年の実行委員長を務めますので、宜しくお願い致します。
開催日は2019年6月29日(土)、場所は例年通り福岡ファッションビルです。参加してね。

すでに準備は進んでおり、昨年末にスポンサー募集のお知らせを公開しました。
嬉しいことにプラチナスポンサー、ゴールドスポンサー、コーヒースポンサーは売り切れて、現在募集中はシルバースポンサーとブロンズスポンサーとなっています。
スポンサーに興味ある企業がありましたら、ぜひサイトから資料をダウンロードしてください。

phpcon.fukuoka.jp

2019年の抱負を書いてみる

明けましておめでとうございます(した)。2019年になって既に1週間が経過しました。今年も宜しくお願いします。

年末年始は娘が結膜炎発症というイベントもあり、ずっと福岡の自宅で過ごしました。
そのためまとまった時間ができた(というか作った)ので、普段やる時間が作りにくいプログラミング的なことをやりました。

2019年にやりたいなと思ってることを載せてみます。達成するできるかは別として。

技術書を読む

これまで休みの日でも何かしらコード書いていたので、今年は書籍からのインプットを増やしたいと思ってます。
せっかく会社にはたくさんの書籍があるのでそれを活用しないのはもったいない。

(文庫本のような活字本はホント苦手というか無理なので読まない。)

Tipsを溜める、共有する

書籍とか業務とかで得たTipsやノウハウは、脳内ではなく文字として蓄積したい。
それを拙くてもアウトプットする。(特に社内)
これまでOneNoteを使ってたけどやっぱりコードを書くには向いてないので、昨年末からBoostnoteを使ってみてます。今のところいい感じ。

boostnote.io

適度に運動する

運動不足のせいか、昨年は体調を崩すことがこれまでより多かったので、基礎体力を向上するための運動をする。

旅行をする

家族旅行でどっか行きたい。

OSSに貢献する

ドキュメントのタイポを修正してプルリクエスト出すとかでも、やらないより全然いいと思ってます。
C#とかお手伝いできるものがあったら声かけてください。

  • Fukuoka.NETの開催をもうちょっと増やす
  • PHPカンファレンス福岡2019を楽しんでやる
  • 適度に休息をとる

書くとキリがないしハードル上がっちゃうのでこれくらいで。今年も宜しくお願い致します。


弊社のボスが書いたブログが良い内容なので貼っとく。エンジニアリングなロールでも当てはまるものはあるのではないか。

koji-kchc.hatenablog.com