Skip to content

Commit 0c73b09

Browse files
committed
Using MediatR behaviors instead of Autofac decorators. Solves dotnet-architecture#187
1 parent 86ca13a commit 0c73b09

4 files changed

Lines changed: 40 additions & 67 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using MediatR;
2+
using Microsoft.Extensions.Logging;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Threading.Tasks;
7+
8+
namespace Ordering.API.Infrastructure.Behaviors
9+
{
10+
public class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
11+
{
12+
private readonly ILogger<LoggingBehavior<TRequest, TResponse>> _logger;
13+
public LoggingBehavior(ILogger<LoggingBehavior<TRequest, TResponse>> logger) => _logger = logger;
14+
15+
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next)
16+
{
17+
_logger.LogInformation($"Handling {typeof(TRequest).Name}");
18+
var response = await next();
19+
_logger.LogInformation($"Handled {typeof(TResponse).Name}");
20+
return response;
21+
}
22+
}
23+
}

src/Services/Ordering/Ordering.API/Application/Decorators/ValidatorDecorator.cs renamed to src/Services/Ordering/Ordering.API/Application/Behaviors/ValidatorBehavior.cs

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,23 @@
11
using FluentValidation;
22
using MediatR;
3+
using Microsoft.Extensions.Logging;
34
using Ordering.Domain.Exceptions;
45
using System;
56
using System.Collections.Generic;
67
using System.Linq;
78
using System.Threading.Tasks;
89

9-
namespace Ordering.API.Application.Decorators
10+
namespace Ordering.API.Infrastructure.Behaviors
1011
{
11-
public class ValidatorDecorator<TRequest, TResponse>
12-
: IAsyncRequestHandler<TRequest, TResponse>
13-
where TRequest : IRequest<TResponse>
12+
public class ValidatorBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
1413
{
15-
private readonly IAsyncRequestHandler<TRequest, TResponse> _inner;
1614
private readonly IValidator<TRequest>[] _validators;
15+
public ValidatorBehavior(IValidator<TRequest>[] validators) => _validators = validators;
1716

18-
19-
public ValidatorDecorator(
20-
IAsyncRequestHandler<TRequest, TResponse> inner,
21-
IValidator<TRequest>[] validators)
22-
{
23-
_inner = inner;
24-
_validators = validators;
25-
}
26-
27-
public async Task<TResponse> Handle(TRequest message)
17+
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next)
2818
{
2919
var failures = _validators
30-
.Select(v => v.Validate(message))
20+
.Select(v => v.Validate(request))
3121
.SelectMany(result => result.Errors)
3222
.Where(error => error != null)
3323
.ToList();
@@ -37,9 +27,8 @@ public async Task<TResponse> Handle(TRequest message)
3727
throw new OrderingDomainException(
3828
$"Command Validation Errors for type {typeof(TRequest).Name}", new ValidationException("Validation exception", failures));
3929
}
40-
41-
var response = await _inner.Handle(message);
4230

31+
var response = await next();
4332
return response;
4433
}
4534
}

src/Services/Ordering/Ordering.API/Application/Decorators/LogDecorator.cs

Lines changed: 0 additions & 34 deletions
This file was deleted.

src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@
33
using FluentValidation;
44
using MediatR;
55
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
6-
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Decorators;
7-
using Ordering.API.Application.Decorators;
86
using Ordering.API.Application.DomainEventHandlers.OrderStartedEvent;
97
using Ordering.API.Application.Validations;
10-
using Ordering.Domain.Events;
8+
using Ordering.API.Infrastructure.Behaviors;
119
using System.Collections.Generic;
1210
using System.Linq;
1311
using System.Reflection;
@@ -33,7 +31,7 @@ protected override void Load(ContainerBuilder builder)
3331
.Where(i => i.IsClosedTypeOf(typeof(IAsyncNotificationHandler<>)))
3432
.Select(i => new KeyedService("IAsyncNotificationHandler", i)))
3533
.AsImplementedInterfaces();
36-
34+
3735

3836
builder
3937
.RegisterAssemblyTypes(typeof(CreateOrderCommandValidator).GetTypeInfo().Assembly)
@@ -45,25 +43,22 @@ protected override void Load(ContainerBuilder builder)
4543
{
4644
var componentContext = context.Resolve<IComponentContext>();
4745
return t => { object o; return componentContext.TryResolve(t, out o) ? o : null; };
48-
});
46+
});
4947

5048
builder.Register<MultiInstanceFactory>(context =>
5149
{
5250
var componentContext = context.Resolve<IComponentContext>();
5351

54-
return t => (IEnumerable<object>)componentContext.Resolve(typeof(IEnumerable<>).MakeGenericType(t));
52+
return t =>
53+
{
54+
var resolved = (IEnumerable<object>)componentContext.Resolve(typeof(IEnumerable<>).MakeGenericType(t));
55+
return resolved;
56+
};
5557
});
5658

57-
58-
59-
builder.RegisterGenericDecorator(typeof(LogDecorator<,>),
60-
typeof(IAsyncRequestHandler<,>),
61-
"IAsyncRequestHandler")
62-
.Keyed("handlerDecorator", typeof(IAsyncRequestHandler<,>));
59+
builder.RegisterGeneric(typeof(LoggingBehavior<,>)).As(typeof(IPipelineBehavior<,>));
60+
builder.RegisterGeneric(typeof(ValidatorBehavior<,>)).As(typeof(IPipelineBehavior<,>));
6361

64-
builder.RegisterGenericDecorator(typeof(ValidatorDecorator<,>),
65-
typeof(IAsyncRequestHandler<,>),
66-
fromKey: "handlerDecorator");
6762
}
6863
}
6964
}

0 commit comments

Comments
 (0)