У меня есть ASP.NET Core API, где я пытаюсь использовать FluentValidation с Mediatr.
В настоящее время, когда метод контроллера пытается вызвать Send для экземпляра mediatr, он генерирует:
Exception thrown: 'System.InvalidOperationException' in Microsoft.Extensions.DependencyInjection.dll: 'Unable to resolve service for type 'GetApplicationQuery' while attempting to activate 'GetApplicationQueryValidator'.'
Запрос, валидатор и класс ответа выглядят так:
public class GetApplicationQuery : IRequest<Response>
{
private string _name;
public GetApplicationQuery(string name)
{
_name = name;
}
public string Name { get { return _name; } }
}
public class GetApplicationQueryHandler : IRequestHandler<GetApplicationQuery, Response>
{
public GetApplicationQueryHandler() { }
public async Task<Response> Handle(GetApplicationQuery request, CancellationToken cancellationToken)
{
return new Response("yadda yadda");
}
}
public class GetApplicationQueryValidator : AbstractValidator<GetApplicationQuery>
{
public GetApplicationQueryValidator(GetApplicationQuery request)
{
RuleFor(m => m.Name).MinimumLength(30).WithMessage("Name must be greater than 30 characters, long");
}
}
public class Response
{
private readonly IList<string> _messages = new List<string>();
public IEnumerable<string> Errors { get; }
public object Result { get; }
public Response() => Errors = new ReadOnlyCollection<string>(_messages);
public Response(object result) : this() => Result = result;
public Response AddError(string message)
{
_messages.Add(message);
return this;
}
}
Конфигурация, которую я имею в классе Startup, выглядит так:
public void ConfigureServices(IServiceCollection services)
{
AddMediatr(services);
services.AddMvc().AddFluentValidation(fv =>
{
fv.RegisterValidatorsFromAssemblyContaining<Startup>();
fv.RunDefaultMvcValidationAfterFluentValidationExecutes = false;
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
private static void AddMediatr(IServiceCollection services)
{
const string applicationAssemblyName = "ApplicationApi";
var assembly = AppDomain.CurrentDomain.Load(applicationAssemblyName);
AssemblyScanner
.FindValidatorsInAssembly(assembly)
.ForEach(result => services.AddScoped(result.InterfaceType, result.ValidatorType));
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(ValidatorHandler<,>));
services.AddMediatR(assembly);
}
Я предполагаю, что у меня неправильная конфигурация, но я несколько раз менял конфигурацию, но безуспешно.
Любое руководство будет высоко оценено
GetApplicationQueryValidator
принимает GetApplicationQuery
как зависимость конструктора, но коллекция не знает об этом, чтобы иметь возможность внедрить его.
Также не видно, как его использовать в этом валидаторе. Я бы предложил удалить GetApplicationQuery
из конструктора, так как он не выглядит нужным.
public class GetApplicationQueryValidator : AbstractValidator<GetApplicationQuery> {
public GetApplicationQueryValidator() {
RuleFor(m => m.Name).MinimumLength(30).WithMessage("Name must be greater than 30 characters, long");
}
}
Это решило проблему. Затем я дважды запустил валидаторы и понял, что мне не нужен вызов AddFluentValidation в ConfigureServices.
Куда вы добавляете
GetApplicationQuery
в коллекцию услуг?GetApplicationQueryValidator
принимает это как зависимость конструктора, но коллекция не знает об этом, чтобы иметь возможность внедрить его. Также не видно, как его использовать.