diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationMiddleware.cs index 2a8c48b1c5..e83e240c85 100644 --- a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationMiddleware.cs +++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationMiddleware.cs @@ -23,15 +23,13 @@ namespace Microsoft.AspNetCore.RequestLocalization public async Task InvokeAsync(HttpContext context, RequestDelegate next) { + var middleware = new RequestLocalizationMiddleware( next, - new OptionsWrapper( - await _requestLocalizationOptionsProvider.GetLocalizationOptionsAsync() -), - _loggerFactory + new OptionsWrapper(await _requestLocalizationOptionsProvider.GetLocalizationOptionsAsync()), _loggerFactory ); await middleware.Invoke(context); } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationOptionsFactory.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationOptionsFactory.cs deleted file mode 100644 index 10cce6a776..0000000000 --- a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationOptionsFactory.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Collections.Generic; -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.Options; -using Volo.Abp.Options; - -namespace Microsoft.AspNetCore.RequestLocalization -{ - public class AbpRequestLocalizationOptionsFactory : AbpOptionsFactory - { - private readonly IAbpRequestLocalizationOptionsProvider _abpRequestLocalizationOptionsProvider; - - public AbpRequestLocalizationOptionsFactory( - IAbpRequestLocalizationOptionsProvider abpRequestLocalizationOptionsProvider, - IEnumerable> setups, - IEnumerable> postConfigures) - : base( - setups, - postConfigures) - { - _abpRequestLocalizationOptionsProvider = abpRequestLocalizationOptionsProvider; - } - - public override RequestLocalizationOptions Create(string name) - { - return _abpRequestLocalizationOptionsProvider.GetLocalizationOptions(); - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationOptionsManager.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationOptionsManager.cs new file mode 100644 index 0000000000..3748e6ff6c --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationOptionsManager.cs @@ -0,0 +1,32 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Options; +using Volo.Abp.Options; + +namespace Microsoft.AspNetCore.RequestLocalization +{ + public class AbpRequestLocalizationOptionsManager : AbpDynamicOptionsManager + { + private RequestLocalizationOptions _options; + + private readonly IAbpRequestLocalizationOptionsProvider _abpRequestLocalizationOptionsProvider; + + public AbpRequestLocalizationOptionsManager( + IOptionsFactory factory, + IAbpRequestLocalizationOptionsProvider abpRequestLocalizationOptionsProvider) + : base(factory) + { + _abpRequestLocalizationOptionsProvider = abpRequestLocalizationOptionsProvider; + } + + public override RequestLocalizationOptions Get(string name) + { + return _options ?? base.Get(name); + } + + protected override async Task OverrideOptionsAsync(string name, RequestLocalizationOptions options) + { + _options = await _abpRequestLocalizationOptionsProvider.GetLocalizationOptionsAsync(); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/DefaultAbpRequestLocalizationOptionsProvider.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/DefaultAbpRequestLocalizationOptionsProvider.cs index eca6990649..24713651f5 100644 --- a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/DefaultAbpRequestLocalizationOptionsProvider.cs +++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/DefaultAbpRequestLocalizationOptionsProvider.cs @@ -11,7 +11,6 @@ using Nito.AsyncEx; using Volo.Abp.DependencyInjection; using Volo.Abp.Localization; using Volo.Abp.Settings; -using Volo.Abp.Threading; namespace Microsoft.AspNetCore.RequestLocalization { @@ -33,16 +32,6 @@ namespace Microsoft.AspNetCore.RequestLocalization _optionsAction = optionsAction; } - public RequestLocalizationOptions GetLocalizationOptions() - { - if (_requestLocalizationOptions != null) - { - return _requestLocalizationOptions; - } - - return AsyncHelper.RunSync(GetLocalizationOptionsAsync); - } - public async Task GetLocalizationOptionsAsync() { if (_requestLocalizationOptions == null) diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/IAbpRequestLocalizationOptionsProvider.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/IAbpRequestLocalizationOptionsProvider.cs index cb4daec7f2..aea718b7cb 100644 --- a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/IAbpRequestLocalizationOptionsProvider.cs +++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/IAbpRequestLocalizationOptionsProvider.cs @@ -8,8 +8,6 @@ namespace Microsoft.AspNetCore.RequestLocalization { void InitLocalizationOptions(Action optionsAction = null); - RequestLocalizationOptions GetLocalizationOptions(); - Task GetLocalizationOptionsAsync(); } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs index fad534949d..c97c3787e7 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs @@ -38,7 +38,7 @@ namespace Volo.Abp.AspNetCore AddAspNetServices(context.Services); context.Services.AddObjectAccessor(); - context.Services.Replace(ServiceDescriptor.Transient, AbpRequestLocalizationOptionsFactory>()); + context.Services.AddAbpDynamicOptions(); } private static void AddAspNetServices(IServiceCollection services) diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Options/AbpDynamicOptionsManager.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Options/AbpDynamicOptionsManager.cs index af40ff1825..43d98aead4 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Options/AbpDynamicOptionsManager.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Options/AbpDynamicOptionsManager.cs @@ -16,9 +16,9 @@ namespace Volo.Abp.Options public virtual Task SetAsync(string name) { - return OverrideOptionsAsync(base.Get(name)); + return OverrideOptionsAsync(name, base.Get(name)); } - protected abstract Task OverrideOptionsAsync(T options); + protected abstract Task OverrideOptionsAsync(string name, T options); } } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Options/AbpOptionsFactory.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Options/AbpOptionsFactory.cs index ecbe0d8271..e2a7a7bf53 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Options/AbpOptionsFactory.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Options/AbpOptionsFactory.cs @@ -4,21 +4,44 @@ using Microsoft.Extensions.Options; namespace Volo.Abp.Options { //TODO: Derive from OptionsFactory when this is released: https://github.com/aspnet/Options/pull/258 (or completely remove this!) + // https://github.com/dotnet/runtime/blob/master/src/libraries/Microsoft.Extensions.Options/src/OptionsFactory.cs public class AbpOptionsFactory : IOptionsFactory where TOptions : class, new() { private readonly IEnumerable> _setups; private readonly IEnumerable> _postConfigures; + private readonly IEnumerable> _validations; - public AbpOptionsFactory(IEnumerable> setups, IEnumerable> postConfigures) + public AbpOptionsFactory( + IEnumerable> setups, + IEnumerable> postConfigures) + : this(setups, postConfigures, validations: null) + { + + } + + public AbpOptionsFactory( + IEnumerable> setups, + IEnumerable> postConfigures, + IEnumerable> validations) { _setups = setups; _postConfigures = postConfigures; + _validations = validations; } public virtual TOptions Create(string name) { var options = new TOptions(); + ConfigureOptions(name, options); + PostConfigureOptions(name, options); + ValidateOptions(name, options); + + return options; + } + + protected virtual void ConfigureOptions(string name, TOptions options) + { foreach (var setup in _setups) { if (setup is IConfigureNamedOptions namedSetup) @@ -30,13 +53,34 @@ namespace Volo.Abp.Options setup.Configure(options); } } + } + protected virtual void PostConfigureOptions(string name, TOptions options) + { foreach (var post in _postConfigures) { post.PostConfigure(name, options); } + } - return options; + protected virtual void ValidateOptions(string name, TOptions options) + { + if (_validations != null) + { + var failures = new List(); + foreach (var validate in _validations) + { + var result = validate.Validate(name, options); + if (result.Failed) + { + failures.AddRange(result.Failures); + } + } + if (failures.Count > 0) + { + throw new OptionsValidationException(name, typeof(TOptions), failures); + } + } } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/AbpAbpLdapOptionsFactory.cs b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/AbpAbpLdapOptionsManager.cs similarity index 61% rename from framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/AbpAbpLdapOptionsFactory.cs rename to framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/AbpAbpLdapOptionsManager.cs index 9579e169be..57d13693b4 100644 --- a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/AbpAbpLdapOptionsFactory.cs +++ b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/AbpAbpLdapOptionsManager.cs @@ -1,36 +1,22 @@ using System; -using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.Extensions.Options; using Volo.Abp.Options; using Volo.Abp.Settings; -using Volo.Abp.Threading; namespace Volo.Abp.Ldap { - public class AbpAbpLdapOptionsFactory : AbpOptionsFactory + public class AbpAbpLdapOptionsManager : AbpDynamicOptionsManager { protected ISettingProvider SettingProvider { get; } - public AbpAbpLdapOptionsFactory( - IEnumerable> setups, - IEnumerable> postConfigures, - ISettingProvider settingProvider) - : base(setups, postConfigures) + public AbpAbpLdapOptionsManager(IOptionsFactory factory, ISettingProvider settingProvider) + : base(factory) { SettingProvider = settingProvider; } - public override AbpLdapOptions Create(string name) - { - var options = base.Create(name); - - AsyncHelper.RunSync(() => OverrideOptionsAsync(options)); - - return options; - } - - protected virtual async Task OverrideOptionsAsync(AbpLdapOptions options) + protected override async Task OverrideOptionsAsync(string name, AbpLdapOptions options) { options.ServerHost = await GetSettingOrDefaultValue(LdapSettingNames.ServerHost, options.ServerHost); options.ServerPort = await SettingProvider.GetAsync(LdapSettingNames.ServerPort, options.ServerPort); diff --git a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/AbpLdapModule.cs b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/AbpLdapModule.cs index c842d4d76b..3366f3d70f 100644 --- a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/AbpLdapModule.cs +++ b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/AbpLdapModule.cs @@ -18,8 +18,7 @@ namespace Volo.Abp.Ldap { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Replace(ServiceDescriptor.Transient, AbpAbpLdapOptionsFactory>()); - context.Services.Replace(ServiceDescriptor.Scoped, OptionsManager>()); + context.Services.AddAbpDynamicOptions(); var configuration = context.Services.GetConfiguration(); var ldapConfiguration = configuration["Ldap"]; diff --git a/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/LdapOptions_Tests.cs b/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/LdapOptions_Tests.cs index 8ec7ef94c6..d6e6e1fc29 100644 --- a/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/LdapOptions_Tests.cs +++ b/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/LdapOptions_Tests.cs @@ -15,7 +15,7 @@ namespace Volo.Abp.Ldap [Fact] public void Should_Resolve_AbpAbpLdapOptionsFactory() { - GetRequiredService>().ShouldBeOfType(typeof(AbpAbpLdapOptionsFactory)); + GetRequiredService>().ShouldBeOfType(typeof(AbpAbpLdapOptionsManager)); } } } diff --git a/modules/blogging/app/Volo.BloggingTestApp/BloggingTestAppModule.cs b/modules/blogging/app/Volo.BloggingTestApp/BloggingTestAppModule.cs index 600cc05f84..c41beef251 100644 --- a/modules/blogging/app/Volo.BloggingTestApp/BloggingTestAppModule.cs +++ b/modules/blogging/app/Volo.BloggingTestApp/BloggingTestAppModule.cs @@ -166,7 +166,7 @@ namespace Volo.BloggingTestApp app.UseAuthentication(); - app.UseRequestLocalization(app.ApplicationServices.GetRequiredService>().Value); + app.UseAbpRequestLocalization(); app.UseConfiguredEndpoints(); diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityOptionsManager.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityOptionsManager.cs index 5735f36051..8ff4c141eb 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityOptionsManager.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityOptionsManager.cs @@ -19,7 +19,7 @@ namespace Volo.Abp.Identity SettingProvider = settingProvider; } - protected override async Task OverrideOptionsAsync(IdentityOptions options) + protected override async Task OverrideOptionsAsync(string name, IdentityOptions options) { options.Password.RequiredLength = await SettingProvider.GetAsync(IdentitySettingNames.Password.RequiredLength, options.Password.RequiredLength); options.Password.RequiredUniqueChars = await SettingProvider.GetAsync(IdentitySettingNames.Password.RequiredUniqueChars, options.Password.RequiredUniqueChars);