zymlabs / nswag-fluentvalidation

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

FluentValidation 10 compatiblity #9

Closed sandord closed 3 years ago

sandord commented 3 years ago

Today I noticed that this library doesn't work with FluentValidation 10.

I'm getting this runtime exception:

Application terminated unexpectedly. System.AggregateException: Some services are not able to be constructed (Error while
validating the service descriptor 'ServiceType: ZymLabs.NSwag.FluentValidation.FluentValidationSchemaProcessor Lifetime:
Singleton ImplementationType: ZymLabs.NSwag.FluentValidation.FluentValidationSchemaProcessor': Cannot consume scoped
service 'FluentValidation.IValidatorFactory' from singleton 
'ZymLabs.NSwag.FluentValidation.FluentValidationSchemaProcessor'.)
 ---> System.InvalidOperationException: Error while validating the service descriptor 'ServiceType: 
ZymLabs.NSwag.FluentValidation.FluentValidationSchemaProcessor Lifetime: Singleton ImplementationType: 
ZymLabs.NSwag.FluentValidation.FluentValidationSchemaProcessor': Cannot consume scoped service 
'FluentValidation.IValidatorFactory' from singleton 'ZymLabs.NSwag.FluentValidation.FluentValidationSchemaProcessor'.
geoffreytran commented 3 years ago

You may need to update your Startup.cs dependency injection to use scoped instead of singleton instantiation. FluentValidation 10 switched to scoped services.

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    // 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);
        })

    services.AddOpenApiDocument((settings, serviceProvider) =>
    {
        var fluentValidationSchemaProcessor = serviceProvider.CreateScope().ServiceProvider.GetService<FluentValidationSchemaProcessor>();

        // Add the fluent validations schema processor
        settings.SchemaProcessors.Add(fluentValidationSchemaProcessor);
    });

    // Add the FluentValidationSchemaProcessor as a scoped service
    serviceCollection.AddScoped<FluentValidationSchemaProcessor>();
}
sandord commented 3 years ago

That worked for me. Thanks a lot!