gpt4 book ai didi

asp.net-core - FluentValidation 装饰器不适用于 autofac 和 mediator

转载 作者:行者123 更新时间:2023-12-01 20:25:14 26 4
gpt4 key购买 nike

我正在尝试使用 CQRS 模式设置 ASP.NET Core 应用程序。为了帮助实现这一目标,我正在使用这些库:

"Autofac.Extensions.DependencyInjection": "4.0.0-rc3-280",
"FluentValidation": "6.4.0-beta3",
"MediatR": "2.1.0"

我完成了所有必需的设置,Mediatr 有效,依赖项注入(inject)有效,但是,我的代码在进入处理程序之前没有通过验证。我认为我在注册验证装饰器时遇到问题。由于我使用的大多数库最近都进行了更新和更改,以支持 ASP.NET Core。我的配置缺少什么?应该怎样呢?

我的配置

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(不确定我是否真的需要它。)

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;
}
}

验证器处理程序

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;


}
}

在这个类中,我的代码直接进入public UserDomain Handle(GetUserByEmailQuery message)而不进行验证。

最佳答案

问题出在这一行:

typeof(IRequestHandler<,>), fromKey: "handler", toKey: "Validator")

它找不到处理程序键。
因此,我通过首先注册程序集中的所有类型(但不包括 RequestHandler)来分割类型的注册。然后使用关键的处理程序注册RequestHandler。

public IServiceProvider ConfigureServices(IServiceCollection services)
{

var builder = new ContainerBuilder();
builder.RegisterAssemblyTypes(typeof(IMediator).GetTypeInfo().Assembly).AsImplementedInterfaces();
builder.RegisterAssemblyTypes(typeof(GetUserByEmailQuery).GetTypeInfo().Assembly)
.Where(t => !t.IsClosedTypeOf(typeof(IRequestHandler<,>)))
.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.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.As(type => type.GetInterfaces()
.Where(interfaceType => interfaceType.IsClosedTypeOf(typeof(IRequestHandler<,>)))
.Select(interfaceType => new KeyedService("handler", interfaceType)))
.InstancePerLifetimeScope();

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>();
}

希望这有帮助!

关于asp.net-core - FluentValidation 装饰器不适用于 autofac 和 mediator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38280139/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com