AlexTeixeira/Askmethat-Aspnet-JsonLocalizer

Fluent validation

jpbayard opened this issue · 2 comments

Hi,
We're using FluentValidation in our project and we want to add localization to our custom validators.
Their documentation suggests to use IStringLocalizer interface to apply localized messages.

We want to use Json localization files rather than resx, so we use your library.

We inject the IJsonStringLocalizer the same way as IStringLocalizer as suggested from FluentValidation documentation

public class AccountValidator : AccountBaseValidator<Account>
  {
      public AccountValidator(IJsonStringLocalizer<IAnyEntity> localizer) : base(localizer)
      {

      }
  }

We now have the problem that IJsonStringLocalizer is a scoped service and our validator is a singleton.
We then have this exception on startup :

System.InvalidOperationException: Cannot resolve 'FluentValidation.IValidator1[IGSoft.WinPrest.Model.Account]' from root provider because it requires scoped service 'Askmethat.Aspnet.JsonLocalizer.Localizer.IJsonStringLocalizer1[IGSoft.Common.Model.Model.Interface.IAnyEntity]'. 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 C:\Projects\FluentValidation\src\FluentValidation.AspNetCore\ServiceProviderValidatorFactory.cs:line 32 at FluentValidation.ValidatorFactoryBase.GetValidator(Type type) in C:\Projects\FluentValidation\src\FluentValidation\ValidatorFactoryBase.cs:line 41 at MicroElements.Swashbuckle.FluentValidation.FluentValidationRules.Apply(OpenApiSchema schema, SchemaFilterContext context) in /home/travis/build/micro-elements/MicroElements.Swashbuckle.FluentValidation/src/MicroElements.Swashbuckle.FluentValidation/FluentValidationRules.cs:line 52

Indeed there this is indeed a scoped declaration.

`
internal static void AddJsonLocalizationServices(IServiceCollection services)
{
_ = services.AddMemoryCache();
_ = services.AddSingleton<IStringLocalizerFactory, JsonStringLocalizerFactory>();
_ = services.AddScoped<IJsonStringLocalizer, JsonStringLocalizer>();
_ = services.AddScoped(typeof(IJsonStringLocalizer<>), typeof(JsonStringLocalizerOfT<>));
_ = services.AddScoped<IStringLocalizer, JsonStringLocalizer>();
_ = services.AddScoped(typeof(IStringLocalizer<>), typeof(JsonStringLocalizerOfT<>));

}
`
Do you have an idea of a way to manage this case?
Thanks !

its not a jsonserializer problem, by design you should not be injecting any transient or scoped service in a singleton.. what you can do for a workaround is build your service in a new collection like this https://docs.microsoft.com/en-us/ef/core/cli/dbcontext-creation?tabs=dotnet-core-cli``

Hello,

@aloksharma1 is right, and using a singleton for the locator is not recommended because of the live update of the culture.