ASP.NET Core MediatRのパイプラインでログを出力する
ASP.NET Core
のプロジェクトで、MediatR
のパイプライン機能を利用してログを出力を行います。
ASP.NET Coreに導入したMediatRのラッパークラスを作成するで紹介した構成に、ログ出力のパイプラインを追加します。
パッケージのインストール
アプリケーション層でログ出力できるようにMicrosoft.Extensions.Logging
のパッケージをインストールします。
$ cd App.Application # アプリケーション層に移動
$ dotnet add package Microsoft.Extensions.Logging
IPipelineBehaviorの作成
MediatR
にはハンドラ処理の前後に処理を組み込む仕組みがあります。
IPipelineBehavior
を継承したクラスを作成することにより、この仕組みを実現します。
以下のように、実装します。
LoggingBehavior.cs
using MediatR;
using Microsoft.Extensions.Logging;
namespace App.Application.Core;
public class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
where TRequest : IRequest<TResponse>
where TResponse : IResult
{
private readonly ILogger<LoggingBehavior<TRequest, TResponse>> _logger;
public LoggingBehavior(ILogger<LoggingBehavior<TRequest, TResponse>> logger)
{
_logger = logger;
}
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
{
_logger.LogInformation("処理開始: " + typeof(TRequest).Name);
var response = await next();
_logger.LogInformation("処理終了: " + typeof(TRequest).Name);
return response;
}
}
ジェネリックのTRequest
には入力クラス、TResponse
には出力クラスが対応しています。
where
で入力クラスと出力クラスを指定することにより、特定のハンドラのみパイプライン処理を行うような動作が可能です。
今回はすべてのハンドラでバリデーションチェックを行いたいので、以下のように指定しています。
入力クラスはIRequest<TResponse>
としているため、実質すべての入力クラスが対象となります。(MediatR
を使用する場合は全ての入力クラスはIRequest
を継承しているため)
IResult
はASP.NET Coreに導入したMediatRのラッパークラスを作成するで定義したインターフェースです。全ての出力クラスはIResult
を継承するように作成していますので、こちらも実質全ての出力クラスが対象となります。
next
の処理で、実際のハンドラが実行されますので、その前後でログ出力を行っています。
DIコンテナに登録
アプリケーション層でDIコンテナに登録する処理で、上記で作成したLoggingBehavior
をDIに登録します。
public static IServiceCollection AddApplication(this IServiceCollection services)
{
services.AddMediatR(Assembly.GetExecutingAssembly());
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>));
return services;
}
以上で設定は完了です。
動作確認
以下のようにWeb層(プレゼン層)からMediatR
を使用してアプリケーション層の処理をコールします。
var result = await mediator.Send(new SampleUpdateCommand(data));
コンソールに以下のログが出力されることが確認できます。
info: App.Application.Core.LoggingBehavior[0]
Handling Action: SampleUpdateCommand
info: App.Application.Core.LoggingBehavior[0]
Handled Action: SampleUpdateCommand