-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Auto Validation does not fire when using SimpleInjector as DI container #37
Comments
Hi there, I’m not familiar with SimpleInjector, as I haven’t used it. Does it integrate well with the default .NET DI provider? One possibility that comes to mind is that the RequestServices property of HttpContext might not be correctly overridden by your SimpleInjector container. If you try adding an IGlobalValidationInterceptor, can you check whether it's being invoked? Another potential issue could be that SimpleInjector might not handle resolving open generics the same way the default DI does. This could affect the filter's ability to locate the validator.
|
Although Simple Injector does integrate with ASP.NET Core, it does so by running Simple Injector side-by-side with the built-in DI Container. This is contrary to how Containers like Autofac function, which tend to replace the buil-in Container. With Simple Injector it's common practice to leave framework and third-party components registered in the built-in Container, while having application components registered inside of Simple Injector. But this model has consequences and migth be the reason why @nhaberl is running into trouble, because when validators are registered inside Simple Injector, any orchestration by AutoValidation that is registered inside of MS.DI, won't know about the existence of these Simpe Injector-registered validators, unless some special wiring exists. I'm not familiar with AutoValidation so I can't specifically describe the fix, but @mvdgun, hopefully you can point me at the class or code that ensures that validators are resolved and invoked. That would give me some starting point to look for. But in more general terms, I think validators can be considered application components as they will contain application-specific business rules and will have dependencies on other application components. It’s best practice to register application components in Simple Injector. But that does require the MS.DI-registered orchestration to either be replaced with something specific that resolves the validators from Simple Injector -or- requires the registration for the orchestration to be made in Simple Injector as well and ensure that the registration for that piece of orchestration inside of MS.DI to simply resolve that component from Simple Injector (cross wiring). E.g. One last note for @nhaberl, please make sure that any code examples that you post are well formatted, readable, and preferably syntax highlighted to make it as easy for us as possible to help you. |
Hi Steven, Thank you for the detailed explanation! As for your questions: Validator registration Validator resolving Line 39 in f4dc05a
From the service provider I resolve a validator via the extension method below: Line 10 in f4dc05a
Validator invoking Line 84 in f4dc05a
If I need to resolve validators from any source other than a I hope I have answered your question, if not please let me know! |
Generally speaking, by taking a hard dependency on But before adding such interception point, let's try something different first, because the main abstraction you are pulling from the DI infrastructure is the @nhaberl, please add the following code and report back whether that helps: services.AddTransient(
typeof(IValidator<T>),
typeof(SimpleInjectorValidatorDispatcher<>));
class SimpleInjectorValidatorDispatcher<T>(Container container) : AbstractValidator<T>
{
public override Task<ValidationResult> ValidateAsync(
ValidationContext<T> context, CancellationToken cancellation = default)
{
var validator = container.GetService<IValidator<T>>();
if (validator is null)
{
return Task.FromResult(new ValidationResult());
}
else
{
return validator.ValidateAsync(context, cancellation);
}
}
} |
@dotnetjunkie thanks a lot, this works!
|
Hi @nhaberl, so it all works? I assume the validation message is as expected? |
Thanks, yes the code provided works and it showed the message like expected. |
Let me explain. I previously referred to MVC's When a request comes in, MVC creates a controller for that. For the creation of controllers, MVC uses a built-in class that does this: Simple Injector users, for instance, use such a custom This is exactly what is happening in the implementation I provided in my previous comment, although this might be a bit harder to see. But because of the lack of an The only However, when AutoValidation calls that I hope this makes sense. |
Hello,
I am workong on asp.net 6 with Simple Injector as DI container which works perfectly but when trying to use AutoValidation nothing is fired.
services.AddFluentValidationAutoValidation(configuration => { configuration.OverrideDefaultResultFactoryWith<CustomResultFactory>(); }); container.Register(typeof(IValidator<>), assemblies, Lifestyle.Singleton);
When trying to validate manually in Controller it works, so I guess the Validator is correct
public class InsertRequestValidator : AbstractValidator<InsertRequestDto> { public InsertRequestValidator() { RuleFor(request => request.Count).InclusiveBetween(1, 1000) .WithMessage("Oida des is afoch zu zvü"); } }
[ApiController] [Route("test")] public class TestController : BaseController
[HttpPost] [Route("command")] public async Task<IActionResult> Command(InsertRequestDto request) { // var validationResult = validator.Validate(request); // if (!validationResult.IsValid) // { // return BadRequest(validationResult.Errors); // } var x = await commandEngine.ExecuteAsync<InsertCommand, int>(new InsertCommand() {Count = request.Count}); return HandleResult(x); }
I have really no idea what I am doing wrong, any help appreciated
The text was updated successfully, but these errors were encountered: