【问题标题】:Unable to resolve Fluent Validation using MediatR without StructureMap无法在没有 StructureMap 的情况下使用 MediatR 解决 Fluent Validation
【发布时间】:2020-08-02 14:04:06
【问题描述】:

尝试在 .Net Core 3.1 微服务中注入 Fluent Validation with MediatR without Structure Map。

在 Nuget 包下面添加:

<PackageReference Include="FluentValidation.AspNetCore" Version="8.6.2" />
<PackageReference Include="MediatR" Version="4.0.1" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="4.0.0" />

Startup.cs:

services.AddMvc(options =>
            {
                options.Filters.Add(typeof(HttpGlobalExceptionFilter));
                options.EnableEndpointRouting = false;
            }).AddControllersAsServices()
            .AddNewtonsoftJson()
            .AddViewLocalization(
                       LanguageViewLocationExpanderFormat.Suffix,
                       opts => { opts.ResourcesPath = "Resources"; })
            .AddDataAnnotationsLocalization()
            .SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
            .AddFluentValidation(fv=> fv.RegisterValidatorsFromAssemblyContaining(typeof(Startup)));

已注册 IPipelineBehavior 和验证器:

services.AddMediatR();

services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidatorBehaviour<,>));

ValidatorBehaviour.cs:

public class ValidatorBehaviour<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
    {
        private readonly IValidator<TRequest>[] _validators;
        public ValidatorBehaviour(IValidator<TRequest>[] validators) => _validators = validators;

        public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
        {
            var failures = _validators
                .Select(v => v.Validate(request))
                .SelectMany(result => result.Errors)
                .Where(error => error != null)
                .ToList();

            if (failures.Any())
            {
                var errorFieldsMessages = failures.Select(x => x.ErrorMessage + ", ").ToArray();

                throw new PomDetailsException(
                    $"Command Validation Errors for type {typeof(TRequest).Name}. " +
                    $"Validation failed : {string.Join(string.Empty, errorFieldsMessages)}", new ValidationException("Validation exception", failures));
            }

            var response = await next();
            return response;
        }
    }

例外:

Unable to resolve service for type 'FluentValidation.IValidator`1[][]' while attempting to activate 

我猜我的配置错误,但我已经多次更改配置,但没有成功。

任何指导将不胜感激

【问题讨论】:

    标签: c# asp.net-core fluentvalidation .net-core-3.1 mediatr


    【解决方案1】:

    您正在尝试解析IValidator&lt;TRequest&gt; 的集合,因此您将构造函数参数指定为IValidator&lt;TRequest&gt;[](数组)。但是框架的 DI 需要为此使用 IEnumerable。如下更新ValidatorBehaviour构造函数,它将按预期工作

    private readonly IEnumerable<IValidator<TRequest>> _validators;
    public ValidatorBehaviour(IEnumerable<IValidator<TRequest>> validators) => _validators = validators;
    

    【讨论】:

    • @Alexander- 现在出现此错误无法解析类型“Microsoft.AspNetCore.Http.HttpContextAccessor”的服务,同时尝试激活“PurchaseOrder.API.Application.Pipeline.PurchaseOrderPreprocessor`1[PurchaseOrder.API .Application.Commands.ReopenPomIdToWorkingCommand]'。已经注册 services.AddSingleton();
    • @Rahul 你能分享一下PurchaseOrderPreprocessor 代码吗?
    • 私有只读 HttpContextAccessor _httpContextAccessor; public PurchaseOrderPreprocessor(HttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; }
    • @Rahul 为构造函数参数和字段设置类型 IHttpContextAccessor(在开头添加了 I)。
    • 让我试着在几分钟后回复你
    猜你喜欢
    • 2023-02-25
    • 1970-01-01
    • 2011-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多