J'essaie de configurer une application ASP.NET Core avec un modèle CQRS. Pour aider à atteindre ce que je utilise ces bibliothèques:Le décorateur FluentValidation ne fonctionne pas avec autofac et mediator
"Autofac.Extensions.DependencyInjection": "4.0.0-rc3-280",
"FluentValidation": "6.4.0-beta3",
"MediatR": "2.1.0"
Je ne tous les paramètres requis, Mediatr fonctionne, les travaux d'injection de dépendance, cependant, mon code ne passe pas par la validation avant d'aller au gestionnaire. Je pense que j'ai un problème avec l'enregistrement du décorateur de validation. Étant donné que la plupart des bibliothèques que j'utilise sont récemment mises à jour et beaucoup modifiées afin de prendre en charge ASP.NET Core. Qu'est-ce qui me manque dans la configuration? Comment ça devrait être?
Ma configuration
public IServiceProvider ConfigureServices(IServiceCollection services)
{
var builder = new ContainerBuilder();
builder.RegisterAssemblyTypes(typeof(IMediator).GetTypeInfo().Assembly).AsImplementedInterfaces();
builder.RegisterAssemblyTypes(typeof(GetUserByEmailQuery).GetTypeInfo().Assembly).AsImplementedInterfaces();
builder.Register<SingleInstanceFactory>(ctx =>
{
var c = ctx.Resolve<IComponentContext>();
return t => c.Resolve(t);
});
builder.Register<MultiInstanceFactory>(ctx =>
{
var c = ctx.Resolve<IComponentContext>();
return t => (IEnumerable<object>)c.Resolve(typeof(IEnumerable<>).MakeGenericType(t));
});
builder.RegisterGenericDecorator(
typeof(MediatorPipeline<,>),
typeof(IRequestHandler<,>), fromKey: "handler", toKey: "Validator")
.Keyed("MediatorPipeline", typeof(IRequestHandler<,>))
.InstancePerLifetimeScope();
//register validator decorator
builder.RegisterGenericDecorator(
typeof(ValidatorHandler<,>),
typeof(IRequestHandler<,>),
"Validator")
.InstancePerLifetimeScope();
builder.Populate(services);
var container = builder.Build();
return container.Resolve<IServiceProvider>();
}
MediatorPipeline (Je ne sais pas si je vraiment besoin.)
public class MediatorPipeline<TRequest, TResponse> : IRequestHandler<TRequest, TResponse> where TRequest : IRequest<TResponse>
{
private readonly IRequestHandler<TRequest, TResponse> _inner;
private readonly IPreRequestHandler<TRequest>[] _preRequestHandlers;
private readonly IPostRequestHandler<TRequest, TResponse>[] _postRequestHandlers;
public MediatorPipeline(IRequestHandler<TRequest, TResponse> inner, IPreRequestHandler<TRequest>[] preRequestHandlers, IPostRequestHandler<TRequest, TResponse>[] postRequestHandlers)
{
_inner = inner;
_preRequestHandlers = preRequestHandlers;
_postRequestHandlers = postRequestHandlers;
}
public TResponse Handle(TRequest message)
{
foreach (var preRequestHandler in _preRequestHandlers)
{
preRequestHandler.Handle(message);
}
var result = _inner.Handle(message);
foreach (var postRequestHandler in _postRequestHandlers)
{
postRequestHandler.Handle(message, result);
}
return result;
}
}
ValidatorHandler
public class ValidatorHandler<TRequest, TResponse> : IRequestHandler<TRequest, TResponse> where TRequest : IRequest<TResponse>
{
private readonly IRequestHandler<TRequest, TResponse> _inner;
private readonly IValidator<TRequest>[] _validators;
public ValidatorHandler(IRequestHandler<TRequest, TResponse> inner, IValidator<TRequest>[] validators)
{
_inner = inner;
_validators = validators;
}
public TResponse Handle(TRequest message)
{
var context = new ValidationContext(message);
var failures = _validators
.Select(v => v.Validate(context))
.SelectMany(result => result.Errors)
.Where(f => f != null)
.ToList();
if (failures.Any())
throw new ValidationException(failures);
return _inner.Handle(message);
}
}
GetUserByEmailQuery.cs
public class GetUserByEmailQuery : IRequest<UserDomain>
{
public string UserEmail { get; set; }
}
public class GetUserByEmailQueryValidator : AbstractValidator<GetUserByEmailQuery>
{
public GetUserByEmailQueryValidator()
{
RuleFor(q => q.UserEmail).NotNull().WithMessage("Email alanı boş bırakılamaz!");
}
public bool Handle(GetUserByEmailQuery message)
{
return true;
}
}
public class GetUserByEmailQueryHandler : IRequestHandler<GetUserByEmailQuery, UserDomain>
{
private readonly AuthDbContext _context;
public GetUserByEmailQueryHandler(AuthDbContext context)
{
_context = context;
}
public UserDomain Handle(GetUserByEmailQuery message)
{
var authUser = _context.Users.Where(x => x.Email.Equals(message.UserEmail)).Include(y => y.UserMeta).Include(z => z.UserRole).FirstOrDefault();
var userDomain = Mapper.Map<UserDomain>(authUser);
return userDomain;
}
}
dans cette classe mon code va directement dans public UserDomain Handle(GetUserByEmailQuery message)
sans faire de validation.
Si vous résolvez un gestionnaire de requêtes ** manuellement ** at-il le décorateur? –