zymlabs / nswag-fluentvalidation

Use FluentValidation rules instead of ComponentModel attributes to define swagger schema.
MIT License
59 stars 13 forks source link

Support for scoped services #6

Closed sandord closed 3 years ago

sandord commented 4 years ago

When I register the validators using the AddValidatorsFromAssemblyContaining service collection extension method, providing the scoped service lifetime (ServiceLifetime.Scoped), I get a lot of instances of the following exception:

[10:25:20 WRN] GetValidator for type 'Xyz.XyzModel' fails.
System.InvalidOperationException: Cannot resolve scoped service 'FluentValidation.IValidator`1[Xyz.XyzModel]' from root provider.
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution(Type serviceType, IServiceScope scope, IServiceScope rootScope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.Microsoft.Extensions.DependencyInjection.ServiceLookup.IServiceProviderEngineCallback.OnResolve(Type serviceType, IServiceScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at FluentValidation.AspNetCore.ServiceProviderValidatorFactory.CreateInstance(Type validatorType) in /home/jskinner/code/FluentValidation/src/FluentValidation.AspNetCore/ServiceProviderValidatorFactory.cs:line 32
   at FluentValidation.ValidatorFactoryBase.GetValidator(Type type) in /home/jskinner/code/FluentValidation/src/FluentValidation/ValidatorFactoryBase.cs:line 41
   at ZymLabs.NSwag.FluentValidation.FluentValidationSchemaProcessor.Process(SchemaProcessorContext context)

Because of this, the validators are not processed.

I think that by creating a service scope and subsequently resolving services from the scope, this problem can be mitigated.

geoffreytran commented 4 years ago

There's a couple workarounds for scoped validators. Given that this library was based off of the Swashbuckle version, have you looked into some of it's workarounds? https://github.com/micro-elements/MicroElements.Swashbuckle.FluentValidation#common-problems-and-workarounds

I haven't had the time to port the HttpContextServiceProviderValidatorFactory yet, but this should solve the problem for HttpContext scopes. The implementation should be usable with this library as is. https://github.com/micro-elements/MicroElements.Swashbuckle.FluentValidation/blob/master/src/MicroElements.Swashbuckle.FluentValidation/HttpContextServiceProviderValidatorFactory.cs

From the MicroElements.Swashbuckle.FluentValidation examples. `
// HttpContextServiceProviderValidatorFactory requires access to HttpContext services.AddHttpContextAccessor();

services
    .AddControllers()
    // Adds fluent validators to Asp.net
    .AddFluentValidation(c =>
    {
        c.RegisterValidatorsFromAssemblyContaining<Startup>();
        // Optionally set validator factory if you have problems with scope resolve inside validators.
        c.ValidatorFactoryType = typeof(HttpContextServiceProviderValidatorFactory);
    })`
geoffreytran commented 3 years ago

The scoped http context provided has been added in the last release.

sandord commented 3 years ago

Sorry for never responding to your reply. I appreciate the effort though and I'm happy to see that support has been added.