|
1 | 1 | using System.Diagnostics; |
2 | 2 | using System.Reflection; |
3 | 3 | using Ardalis.GuardClauses; |
4 | | -using MediatR; |
5 | 4 | using Microsoft.Extensions.Logging; |
| 5 | +using Mediator; |
6 | 6 |
|
7 | 7 | namespace NimblePros.SharedKernel; |
8 | 8 |
|
9 | | -/// <summary> |
10 | | -/// Adds logging for all requests in MediatR pipeline. |
11 | | -/// Configure by adding the service with a scoped lifetime |
12 | | -/// |
13 | | -/// Example for Autofac: |
14 | | -/// builder |
15 | | -/// .RegisterType<Mediator>() |
16 | | -/// .As<IMediator>() |
17 | | -/// .InstancePerLifetimeScope(); |
18 | | -/// |
19 | | -/// builder |
20 | | -/// .RegisterGeneric(typeof(LoggingBehavior<,>)) |
21 | | -/// .As(typeof(IPipelineBehavior<,>)) |
22 | | -/// .InstancePerLifetimeScope(); |
23 | | -/// |
24 | | -/// </summary> |
25 | | -/// <typeparam name="TRequest"></typeparam> |
26 | | -/// <typeparam name="TResponse"></typeparam> |
27 | 9 | public class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> |
28 | | - where TRequest : IRequest<TResponse> |
| 10 | + where TRequest : IRequest<TResponse> |
29 | 11 | { |
30 | | - private readonly ILogger<Mediator> _logger; |
| 12 | + private readonly ILogger<LoggingBehavior<TRequest, TResponse>> _logger; |
31 | 13 |
|
32 | | - public LoggingBehavior(ILogger<Mediator> logger) |
33 | | - { |
34 | | - _logger = logger; |
35 | | - } |
36 | | - |
37 | | - public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken) |
38 | | - { |
39 | | - Guard.Against.Null(request); |
40 | | - if (_logger.IsEnabled(LogLevel.Information)) |
| 14 | + public LoggingBehavior(ILogger<LoggingBehavior<TRequest, TResponse>> logger) |
41 | 15 | { |
42 | | - _logger.LogInformation("Handling {RequestName}", typeof(TRequest).Name); |
43 | | - |
44 | | - // Reflection! Could be a performance concern |
45 | | - Type myType = request.GetType(); |
46 | | - IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties()); |
47 | | - foreach (PropertyInfo prop in props) |
48 | | - { |
49 | | - object? propValue = prop?.GetValue(request, null); |
50 | | - _logger.LogInformation("Property {Property} : {@Value}", prop?.Name, propValue); |
51 | | - } |
| 16 | + _logger = logger; |
52 | 17 | } |
53 | 18 |
|
54 | | - var sw = Stopwatch.StartNew(); |
55 | | - |
56 | | - var response = await next(); |
57 | | - |
58 | | - _logger.LogInformation("Handled {RequestName} with {Response} in {ms} ms", typeof(TRequest).Name, response, sw.ElapsedMilliseconds); |
59 | | - sw.Stop(); |
60 | | - return response; |
61 | | - } |
| 19 | + public async ValueTask<TResponse> Handle( |
| 20 | + TRequest request, |
| 21 | + MessageHandlerDelegate<TRequest, TResponse> next, |
| 22 | + CancellationToken cancellationToken) |
| 23 | + { |
| 24 | + Guard.Against.Null(request); |
| 25 | + if (_logger.IsEnabled(LogLevel.Information)) |
| 26 | + { |
| 27 | + _logger.LogInformation("Handling {RequestName}", typeof(TRequest).Name); |
| 28 | + |
| 29 | + Type myType = request.GetType(); |
| 30 | + IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties()); |
| 31 | + foreach (PropertyInfo prop in props) |
| 32 | + { |
| 33 | + object? propValue = prop?.GetValue(request, null); |
| 34 | + _logger.LogInformation("Property {Property} : {@Value}", prop?.Name, propValue); |
| 35 | + } |
| 36 | + } |
| 37 | + |
| 38 | + var sw = Stopwatch.StartNew(); |
| 39 | + |
| 40 | + var response = await next(request, cancellationToken); |
| 41 | + |
| 42 | + _logger.LogInformation("Handled {RequestName} with {Response} in {ms} ms", typeof(TRequest).Name, response, sw.ElapsedMilliseconds); |
| 43 | + sw.Stop(); |
| 44 | + return response; |
| 45 | + } |
62 | 46 | } |
63 | 47 |
|
0 commit comments