From 9e4770eac21f4046b25eb2d9466ec91894cc3956 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Mon, 11 Feb 2019 14:41:33 +0300 Subject: [PATCH] #792 added ISettingProvider service --- .../Mvc/UI/RazorPages/AbpPageModel.cs | 2 +- .../AbpApplicationBuilderExtensions.cs | 6 +- .../Permissions/PermissionDefinition.cs | 4 + .../Services/ApplicationService.cs | 2 +- .../Abp/Emailing/EmailSenderConfiguration.cs | 10 +- .../Smtp/SmtpEmailSenderConfiguration.cs | 10 +- .../LanguageProviderExtensions.cs | 2 +- .../Volo/Abp/Settings/ISettingProvider.cs | 13 +++ .../Volo/Abp/Settings/SettingDefinition.cs | 31 ++++++ .../Volo/Abp/Settings/SettingProvider.cs | 102 ++++++++++++++++++ .../Abp/Settings/SettingProviderExtensions.cs | 56 ++++++++++ .../Volo/Abp/Settings/SettingValue.cs | 5 +- .../Abp/Settings/SettingProvider_Tests.cs | 30 ++++++ 13 files changed, 256 insertions(+), 17 deletions(-) create mode 100644 framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingProvider.cs create mode 100644 framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProvider.cs create mode 100644 framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProviderExtensions.cs create mode 100644 framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingProvider_Tests.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/RazorPages/AbpPageModel.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/RazorPages/AbpPageModel.cs index 78b9d407a5..8fd16f5864 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/RazorPages/AbpPageModel.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/RazorPages/AbpPageModel.cs @@ -60,7 +60,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.RazorPages public ICurrentTenant CurrentTenant { get; set; } - public ISettingManager SettingManager { get; set; } + public ISettingProvider SettingProvider { get; set; } public IModelStateValidator ModelValidator { get; set; } diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs index 7441e78130..4d7efb1d9d 100644 --- a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs @@ -48,10 +48,10 @@ namespace Microsoft.AspNetCore.Builder using (var scope = app.ApplicationServices.CreateScope()) { var languageProvider = scope.ServiceProvider.GetRequiredService(); - var settingManager = scope.ServiceProvider.GetRequiredService(); + languages = languageProvider.GetLanguages(); - languages = AsyncHelper.RunSync(() => languageProvider.GetLanguagesAsync()); - defaultLanguage = settingManager.GetOrNull(LocalizationSettingNames.DefaultLanguage); + var settingProvider = scope.ServiceProvider.GetRequiredService(); + defaultLanguage = settingProvider.GetOrNull(LocalizationSettingNames.DefaultLanguage); } if (!languages.Any()) diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs index 66c3c78143..db0ea4f977 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs @@ -18,6 +18,10 @@ namespace Volo.Abp.Authorization.Permissions /// public PermissionDefinition Parent { get; private set; } + /// + /// A list of allowed providers to get value of this permission. + /// An empty list indicates that all providers are allowed. + /// public List Providers { get; } public ILocalizableString DisplayName diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs index 0e4b13cada..63a749e259 100644 --- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs @@ -45,7 +45,7 @@ namespace Volo.Abp.Application.Services public ICurrentUser CurrentUser { get; set; } - public ISettingManager SettingManager { get; set; } + public ISettingProvider SettingProvider { get; set; } public IClock Clock { get; set; } diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/EmailSenderConfiguration.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/EmailSenderConfiguration.cs index 3293692cfb..3034481471 100644 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/EmailSenderConfiguration.cs +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/EmailSenderConfiguration.cs @@ -11,16 +11,16 @@ namespace Volo.Abp.Emailing { public virtual string DefaultFromAddress => GetNotEmptySettingValue(EmailSettingNames.DefaultFromAddress); - public virtual string DefaultFromDisplayName => SettingManager.GetOrNull(EmailSettingNames.DefaultFromDisplayName); + public virtual string DefaultFromDisplayName => SettingProvider.GetOrNull(EmailSettingNames.DefaultFromDisplayName); - protected readonly ISettingManager SettingManager; + protected readonly ISettingProvider SettingProvider; /// /// Creates a new . /// - protected EmailSenderConfiguration(ISettingManager settingManager) + protected EmailSenderConfiguration(ISettingProvider settingProvider) { - SettingManager = settingManager; + SettingProvider = settingProvider; } /// @@ -30,7 +30,7 @@ namespace Volo.Abp.Emailing /// Value of the setting protected string GetNotEmptySettingValue(string name) { - var value = SettingManager.GetOrNull(name); + var value = SettingProvider.GetOrNull(name); if (value.IsNullOrEmpty()) { diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Smtp/SmtpEmailSenderConfiguration.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Smtp/SmtpEmailSenderConfiguration.cs index b114cc43dd..678d2cc4f2 100644 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Smtp/SmtpEmailSenderConfiguration.cs +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Smtp/SmtpEmailSenderConfiguration.cs @@ -18,14 +18,14 @@ namespace Volo.Abp.Emailing.Smtp public virtual string Password => GetNotEmptySettingValue(EmailSettingNames.Smtp.Password); - public virtual string Domain => SettingManager.GetOrNull(EmailSettingNames.Smtp.Domain); + public virtual string Domain => SettingProvider.GetOrNull(EmailSettingNames.Smtp.Domain); - public virtual bool EnableSsl => SettingManager.GetOrNull(EmailSettingNames.Smtp.EnableSsl).To(); + public virtual bool EnableSsl => SettingProvider.GetOrNull(EmailSettingNames.Smtp.EnableSsl).To(); - public virtual bool UseDefaultCredentials => SettingManager.GetOrNull(EmailSettingNames.Smtp.UseDefaultCredentials).To(); + public virtual bool UseDefaultCredentials => SettingProvider.GetOrNull(EmailSettingNames.Smtp.UseDefaultCredentials).To(); - public SmtpEmailSenderConfiguration(ISettingManager settingManager) - : base(settingManager) + public SmtpEmailSenderConfiguration(ISettingProvider settingProvider) + : base(settingProvider) { } diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageProviderExtensions.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageProviderExtensions.cs index 5c7ffe6508..951292ac66 100644 --- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageProviderExtensions.cs +++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageProviderExtensions.cs @@ -7,7 +7,7 @@ namespace Volo.Abp.Localization { public static IReadOnlyList GetLanguages(this ILanguageProvider languageProvider) { - return AsyncHelper.RunSync(() => languageProvider.GetLanguagesAsync()); + return AsyncHelper.RunSync(languageProvider.GetLanguagesAsync); } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingProvider.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingProvider.cs new file mode 100644 index 0000000000..608cf49105 --- /dev/null +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingProvider.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using JetBrains.Annotations; + +namespace Volo.Abp.Settings +{ + public interface ISettingProvider + { + Task GetOrNullAsync([NotNull]string name); + + Task> GetAllAsync(); + } +} diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingDefinition.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingDefinition.cs index cbbf810f84..1563de3291 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingDefinition.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingDefinition.cs @@ -36,6 +36,12 @@ namespace Volo.Abp.Settings /// public bool IsVisibleToClients { get; set; } + /// + /// A list of allowed providers to get value of this permission. + /// An empty list indicates that all providers are allowed. + /// + public List Providers { get; } + /// /// Is this setting inherited from parent scopes. /// Default: True. @@ -72,6 +78,31 @@ namespace Volo.Abp.Settings IsEncrypted = isEncrypted; Properties = new Dictionary(); + Providers = new List(); + } + + /// + /// Sets a property in the dictionary. + /// This is a shortcut for nested calls on this object. + /// + public virtual SettingDefinition WithProperty(string key, object value) + { + Properties[key] = value; + return this; + } + + /// + /// Sets a property in the dictionary. + /// This is a shortcut for nested calls on this object. + /// + public virtual SettingDefinition WithProviders(params string[] providers) + { + if (!providers.IsNullOrEmpty()) + { + Providers.AddRange(providers); + } + + return this; } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProvider.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProvider.cs new file mode 100644 index 0000000000..b826a72e49 --- /dev/null +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProvider.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Settings +{ + public class SettingProvider : ISettingProvider, ITransientDependency + { + protected ISettingDefinitionManager SettingDefinitionManager { get; } + protected Lazy> Providers { get; } + protected ISettingEncryptionService SettingEncryptionService { get; } + protected SettingOptions Options { get; } + + public SettingProvider( + IOptions options, + IServiceProvider serviceProvider, + ISettingDefinitionManager settingDefinitionManager, + ISettingEncryptionService settingEncryptionService) + { + SettingDefinitionManager = settingDefinitionManager; + SettingEncryptionService = settingEncryptionService; + + Options = options.Value; + + Providers = new Lazy>( + () => Options + .ValueProviders + .Select(c => serviceProvider.GetRequiredService(c) as ISettingValueProvider) + .ToList(), + true + ); + } + + public virtual async Task GetOrNullAsync(string name) + { + var setting = SettingDefinitionManager.Get(name); + var providers = Enumerable + .Reverse(Providers.Value); + + if (setting.Providers.Any()) + { + providers = providers.Where(p => setting.Providers.Contains(p.Name)); + } + + //TODO: How to implement setting.IsInherited? + + var value = await GetOrNullValueFromProvidersAsync(null, providers, setting); + if (setting.IsEncrypted) + { + value = SettingEncryptionService.Decrypt(setting, value); + } + + return value; + } + + public virtual async Task> GetAllAsync() + { + var settingValues = new Dictionary(); + var settingDefinitions = SettingDefinitionManager.GetAll(); + + foreach (var provider in Providers.Value) + { + foreach (var setting in settingDefinitions) + { + var value = await provider.GetOrNullAsync(setting, null); + if (value != null) + { + if (setting.IsEncrypted) + { + value = SettingEncryptionService.Decrypt(setting, value); + } + + settingValues[setting.Name] = new SettingValue(setting.Name, value); + } + } + } + + return settingValues.Values.ToList(); + } + + protected virtual async Task GetOrNullValueFromProvidersAsync( + string providerKey, + IEnumerable providers, + SettingDefinition setting) + { + foreach (var provider in providers) + { + var value = await provider.GetOrNullAsync(setting, providerKey); + if (value != null) + { + return value; + } + } + + return null; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProviderExtensions.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProviderExtensions.cs new file mode 100644 index 0000000000..d3f372baca --- /dev/null +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProviderExtensions.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Volo.Abp.Threading; + +namespace Volo.Abp.Settings +{ + public static class SettingProviderExtensions + { + public static async Task IsTrueAsync([NotNull] this ISettingProvider settingProvider, [NotNull] string name) + { + Check.NotNull(settingProvider, nameof(settingProvider)); + Check.NotNull(name, nameof(name)); + + return string.Equals( + await settingProvider.GetOrNullAsync(name), + "true", + StringComparison.OrdinalIgnoreCase + ); + } + + public static async Task GetAsync([NotNull] this ISettingProvider settingProvider, [NotNull] string name, T defaultValue = default) + where T : struct + { + Check.NotNull(settingProvider, nameof(settingProvider)); + Check.NotNull(name, nameof(name)); + + var value = await settingProvider.GetOrNullAsync(name); + return value?.To() ?? defaultValue; + } + + public static string GetOrNull([NotNull] this ISettingProvider settingProvider, [NotNull] string name) + { + Check.NotNull(settingProvider, nameof(settingProvider)); + return AsyncHelper.RunSync(() => settingProvider.GetOrNullAsync(name)); + } + + public static List GetAll([NotNull] this ISettingProvider settingProvider) + { + Check.NotNull(settingProvider, nameof(settingProvider)); + return AsyncHelper.RunSync(settingProvider.GetAllAsync); + } + + public static T Get([NotNull] this ISettingProvider settingProvider, [NotNull] string name, T defaultValue = default) + where T : struct + { + return AsyncHelper.RunSync(() => settingProvider.GetAsync(name, defaultValue)); + } + + public static bool IsTrue([NotNull] this ISettingProvider settingProvider, [NotNull] string name) + { + return AsyncHelper.RunSync(() => settingProvider.IsTrueAsync(name)); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingValue.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingValue.cs index 99b2de33f1..d7f48081dd 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingValue.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingValue.cs @@ -1,5 +1,8 @@ -namespace Volo.Abp.Settings +using System; + +namespace Volo.Abp.Settings { + [Serializable] public class SettingValue : NameValue { /// diff --git a/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingProvider_Tests.cs b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingProvider_Tests.cs new file mode 100644 index 0000000000..6b95b0f755 --- /dev/null +++ b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingProvider_Tests.cs @@ -0,0 +1,30 @@ +using System.Threading.Tasks; +using Shouldly; +using Xunit; + +namespace Volo.Abp.Settings +{ + public class SettingProvider_Tests : AbpIntegratedTest + { + private readonly ISettingProvider _settingProvider; + + public SettingProvider_Tests() + { + _settingProvider = GetRequiredService(); + } + + [Fact] + public async Task Should_Get_Null_If_No_Value_Provided_And_No_Default_Value() + { + (await _settingProvider.GetOrNullAsync(TestSettingNames.TestSettingWithoutDefaultValue)) + .ShouldBeNull(); + } + + [Fact] + public async Task Should_Get_Default_Value_If_No_Value_Provided_And_There_Is_A_Default_Value() + { + (await _settingProvider.GetOrNullAsync(TestSettingNames.TestSettingWithDefaultValue)) + .ShouldBe("default-value"); + } + } +}