ใช้ MediatR ใน .NET Core ทำ Logging
ก่อนอื่นถ้าใครยังไม่รู้จัก MediatR หรือว่ายังไม่เคยอ่านบทความก่อนหน้าลองเข้าไปดูรายละเอียดของ MediatR ในบทความ “มาทำความรู้จัก MediatR ใน .NET Core” กันก่อนนะครับ ส่วนในบทความนี้จะแนะนำเกี่ยวกับการทำ request/response logging โดยใช้ MediatR ใน .NET Core
ก่อนอื่นเราสามารถใช้ Pipeline Behavior ใน MediatR ในการปรับแต่งการทำงานของ MediatR โดยเราสามารถสร้าง Behavior ที่จะทำงานก่อนหรือหลังจากการส่งคำสั่งไปยัง Handler ได้ ตัวอย่างด้านล่างจะเป็นวิธีการสร้าง pipeline สำหรับ logging request/response
public sealed class LoggingPipelineBehavior<TRequest, TResponse>(ILogger<LoggingPipelineBehavior<TRequest, TResponse>> logger)
: IPipelineBehavior<TRequest, TResponse>
where TRequest : notnull
{
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
{
var correlationId = Guid.NewGuid();
var requestJson = JsonSerializer.Serialize(request);
logger.LogInformation("Request for {CorrelationId}: {RequestJson}", correlationId, requestJson);
var response = await next();
var responseJson = JsonSerializer.Serialize(response);
logger.LogInformation("Response for {CorrelationId}: {ResponseJson}", correlationId, responseJson);
return response;
}
}
ในตัวอย่างเริ่มต้นเราจะมีการสร้าง class ที่ชื่อว่า LoggingPipelineBehavior ซึ่งจะ implement IPipelineBehavior โดยมีการรับ ILogger มาเพื่อใช้ในการ log ข้อมูล ใน method Handle เราจะทำการ
- เราจะสร้าง random GUID ขึ้นมาเพื่อใช้เป็น correlation id ของ request/response นั้นๆ
- ทำการ serialize request และ log ข้อมูล request
- ทำการส่ง request ไปยัง Handler ต่อไป โดยผ่าน
await next()
- ทำการ serialize response และ log ข้อมูล response
หลังจากนั้นเราก็ทำการ register behavior ที่เราสร้างไว้ใน Program.cs ดังนี้
services.AddMediatR(config =>
{
config.RegisterServicesFromAssembly(applicationAssembly);
config.AddOpenBehavior(typeof(LoggingPipelineBehavior<,>));
});
หลังจากที่รันโปรแกรมแล้วมีการเรียกใช้ request ใดๆ ก็จะมีการ log request/response ออกมาดังรูปด้านบน