【问题标题】:Adding validation using mediatR pipeline behaviour使用 mediatR 管道行为添加验证
【发布时间】:2020-06-01 06:55:47
【问题描述】:

作为管道行为的一部分,尝试在创建客户时设置验证

    public class ValidationBehavoir<TRequest, TResponse> : IPipelineBehavior<TRequest, TRequest>
        where TRequest : IRequest<TResponse>
    { 

        private readonly IEnumerable<IValidator<TRequest>> _validators;

        public ValidationBehavoir(IEnumerable<IValidator<TRequest>> validators)
        {
            _validators = validators;
        }
        public async Task<TRequest> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TRequest> next)
        {

            var context = new ValidationContext(request);
            var failures = _validators.Select(x => x.Validate(context)).SelectMany(x => x.Errors).ToList();

            if(failures.Any())
            {
                throw new ValidationException(failures);
            }

            return await next();
        } 
    }

以下是设置 DI 时添加的服务

            services.AddMediatR(typeof(Program));
            services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavoir<,>));
            services.AddMediatR(typeof(CreateCustomerCommand).GetTypeInfo().Assembly);
            services.AddMediatR(typeof(GetCustomersQuery).GetTypeInfo().Assembly);

But still, getting below error? 
System.ArgumentException: Implementation type 'CustomerApis.PipelineBehaviors.ValidationBehavoir`2[Customers.Service.Command.CreateCustomerCommand,Customers.Domain.Entities.Customer]' can't be converted to service type 'MediatR.IPipelineBehavior`2[Customers.Service.Command.CreateCustomerCommand,Customers.Domain.Entities.Customer]'
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ConstructorCallSite..ctor(ResultCache cache, Type serviceType, ConstructorInfo constructorInfo, ServiceCallSite[] parameterCallSites)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(ResultCache lifetime, Type serviceType, Type implementationType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateOpenGeneric(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain, Int32 slot)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateEnumerable(Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.<>c__DisplayClass7_0.<GetCallSite>b__0(Type type)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)

有人可以帮我吗?

【问题讨论】:

  • 我的处理程序是在单独的程序集中编写的,而验证是在同一个程序集中
  • 有人,请帮帮我。

标签: .net-core mediatr


【解决方案1】:

您可能缺少一些信息(例如每个实体的特定验证器)但是,我会将 services.AddTransient 行移到其他行下方,或者我会尝试这个而不是您拥有的行:

services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());
services.AddMediatR(Assembly.GetExecutingAssembly());
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavoir<,>));

【讨论】:

  • 您好,奥斯卡,感谢您的回复。但是,即使在更改了您上面提到的注册服务的顺序后,我也会遇到同样的错误。如果我评论管道服务注册,我可以点击处理程序并执行。
【解决方案2】:

公共类 ValidationBehavoir : IPipelineBehavior 其中 TRequest : IRequest {

    private readonly IEnumerable<IValidator<TRequest>> _validators;

    public ValidationBehavoir(IEnumerable<IValidator<TRequest>> validators)
    {
        _validators = validators;
    }

    public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
    {
        var context = new ValidationContext(request);
        var failures = _validators.Select(x => x.Validate(context)).SelectMany(x => x.Errors).ToList();

        if (failures.Any())
        {
            throw new ValidationException(failures);
        }

        return await next();
    }
}

公共类 ValidationBehavoir : IPipelineBehavior 其中 TRequest : IRequest {

    private readonly IEnumerable<IValidator<TRequest>> _validators;

    public ValidationBehavoir(IEnumerable<IValidator<TRequest>> validators)
    {
        _validators = validators;
    }

    public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
    {
        var context = new ValidationContext(request);
        var failures = _validators.Select(x => x.Validate(context)).SelectMany(x => x.Errors).ToList();

        if (failures.Any())
        {
            throw new ValidationException(failures);
        }

        return await next();
    }
}

【讨论】:

    【解决方案3】:

    这个解决方案对我有用。

    services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly(), ServiceLifetime.Transient);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-15
      • 1970-01-01
      相关资源
      最近更新 更多