You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
250 lines
8.0 KiB
C#
250 lines
8.0 KiB
C#
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Options;
|
|
using NPin.Framework.SettingManagement.Domain.Options;
|
|
using NPin.Framework.SettingManagement.Domain.Provider;
|
|
using Volo.Abp.DependencyInjection;
|
|
using Volo.Abp.Settings;
|
|
|
|
namespace NPin.Framework.SettingManagement.Domain;
|
|
|
|
public class SettingManager : ISettingManager, ISingletonDependency
|
|
{
|
|
private readonly Lazy<List<ISettingManagementProvider>> _lazyProviders;
|
|
|
|
protected readonly IServiceProvider ServiceProvider;
|
|
protected ISettingDefinitionManager SettingDefinitionManager { get; }
|
|
protected ISettingEncryptionService SettingEncryptionService { get; }
|
|
protected List<ISettingManagementProvider> Providers => _lazyProviders.Value;
|
|
protected SettingManagementOptions Options { get; }
|
|
|
|
public SettingManager(
|
|
IServiceProvider serviceProvider,
|
|
ISettingDefinitionManager settingDefinitionManager,
|
|
ISettingEncryptionService settingEncryptionService,
|
|
IOptions<SettingManagementOptions> options)
|
|
{
|
|
ServiceProvider = serviceProvider;
|
|
SettingDefinitionManager = settingDefinitionManager;
|
|
SettingEncryptionService = settingEncryptionService;
|
|
Options = options.Value;
|
|
|
|
_lazyProviders = new Lazy<List<ISettingManagementProvider>>(CreateSettingManagementProviders, true);
|
|
}
|
|
|
|
protected virtual List<ISettingManagementProvider> CreateSettingManagementProviders()
|
|
{
|
|
using var scope = ServiceProvider.CreateScope();
|
|
|
|
return Options.Providers
|
|
.Select(p => (scope.ServiceProvider.GetRequiredService(p) as ISettingManagementProvider)!)
|
|
.ToList();
|
|
}
|
|
|
|
public virtual Task<string?> GetOrNullAsync(string name, string providerName, string? providerKey,
|
|
bool fallback = true)
|
|
{
|
|
Check.NotNull(name, nameof(name));
|
|
Check.NotNull(providerName, nameof(providerName));
|
|
|
|
return GetOrNullInternalAsync(name, providerName, providerKey, fallback);
|
|
}
|
|
|
|
public virtual async Task<List<SettingValue>> GetAllAsync(string providerName, string? providerKey,
|
|
bool fallback = true)
|
|
{
|
|
Check.NotNull(providerName, nameof(providerName));
|
|
|
|
var settingDefinitions = await SettingDefinitionManager.GetAllAsync();
|
|
var providers = Enumerable.Reverse(Providers)
|
|
.SkipWhile(c => c.Name != providerName);
|
|
|
|
if (!fallback)
|
|
{
|
|
providers = providers.TakeWhile(c => c.Name == providerName);
|
|
}
|
|
|
|
var providerList = providers.Reverse().ToList();
|
|
|
|
if (!providerList.Any())
|
|
{
|
|
return new List<SettingValue>();
|
|
}
|
|
|
|
var settingValues = new Dictionary<string, SettingValue>();
|
|
|
|
foreach (var setting in settingDefinitions)
|
|
{
|
|
string value = null;
|
|
|
|
if (setting.IsInherited)
|
|
{
|
|
foreach (var provider in providerList)
|
|
{
|
|
var providerValue = await provider.GetOrNullAsync(
|
|
setting,
|
|
provider.Name == providerName ? providerKey : null
|
|
);
|
|
if (providerValue != null)
|
|
{
|
|
value = providerValue;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
value = await providerList[0].GetOrNullAsync(
|
|
setting,
|
|
providerKey
|
|
);
|
|
}
|
|
|
|
if (setting.IsEncrypted)
|
|
{
|
|
value = SettingEncryptionService.Decrypt(setting, value);
|
|
}
|
|
|
|
if (value != null)
|
|
{
|
|
settingValues[setting.Name] = new SettingValue(setting.Name, value);
|
|
}
|
|
}
|
|
|
|
return settingValues.Values.ToList();
|
|
}
|
|
|
|
public async Task<Dictionary<string, SettingValue>> GetAllByPrefixAsync(string namePrefix, string providerName,
|
|
string? providerKey, bool fallback = false)
|
|
{
|
|
Check.NotNull(providerName, nameof(providerName));
|
|
|
|
var setting = await SettingDefinitionManager.GetAsync(namePrefix);
|
|
var providers = Enumerable.Reverse(Providers)
|
|
.SkipWhile(c => c.Name != providerName);
|
|
|
|
if (!fallback)
|
|
{
|
|
providers = providers.TakeWhile(c => c.Name == providerName);
|
|
}
|
|
|
|
var providerList = providers.Reverse().ToList();
|
|
if (!providerList.Any())
|
|
{
|
|
return new Dictionary<string, SettingValue>();
|
|
}
|
|
|
|
var settingValues = new Dictionary<string, SettingValue>();
|
|
foreach (var provider in providerList)
|
|
{
|
|
var list = await provider.GetByPrefixAsync(
|
|
setting.Name,
|
|
provider.Name == providerName ? providerKey : null
|
|
);
|
|
foreach (var sv in list)
|
|
{
|
|
if (setting.IsEncrypted)
|
|
{
|
|
sv.Value = SettingEncryptionService.Decrypt(setting, sv.Value);
|
|
}
|
|
|
|
if (sv.Value != null)
|
|
{
|
|
settingValues[sv.Name] = sv;
|
|
}
|
|
}
|
|
}
|
|
|
|
return settingValues;
|
|
}
|
|
|
|
public virtual async Task SetAsync(string name, string? value, string providerName, string? providerKey,
|
|
bool forceToSet = false)
|
|
{
|
|
Check.NotNull(name, nameof(name));
|
|
Check.NotNull(providerName, nameof(providerName));
|
|
|
|
var setting = await SettingDefinitionManager.GetAsync(name);
|
|
|
|
var providers = Enumerable
|
|
.Reverse(Providers)
|
|
.SkipWhile(p => p.Name != providerName)
|
|
.ToList();
|
|
|
|
if (!providers.Any())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (setting.IsEncrypted)
|
|
{
|
|
value = SettingEncryptionService.Encrypt(setting, value);
|
|
}
|
|
|
|
if (providers.Count > 1 && !forceToSet && setting.IsInherited && value != null)
|
|
{
|
|
var fallbackValue = await GetOrNullInternalAsync(name, providers[1].Name, null);
|
|
if (fallbackValue == value)
|
|
{
|
|
//Clear the value if it's same as it's fallback value
|
|
value = null;
|
|
}
|
|
}
|
|
|
|
providers = providers
|
|
.TakeWhile(p => p.Name == providerName)
|
|
.ToList(); //Getting list for case of there are more than one provider with same providerName
|
|
|
|
if (value == null)
|
|
{
|
|
foreach (var provider in providers)
|
|
{
|
|
await provider.ClearAsync(setting, providerKey);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach (var provider in providers)
|
|
{
|
|
await provider.SetAsync(setting, value, providerKey);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected virtual async Task<string?> GetOrNullInternalAsync(string name, string? providerName, string? providerKey,
|
|
bool fallback = true)
|
|
{
|
|
var setting = await SettingDefinitionManager.GetAsync(name);
|
|
var providers = Enumerable
|
|
.Reverse(Providers);
|
|
|
|
if (providerName != null)
|
|
{
|
|
providers = providers.SkipWhile(c => c.Name != providerName);
|
|
}
|
|
|
|
if (!fallback || !setting.IsInherited)
|
|
{
|
|
providers = providers.TakeWhile(c => c.Name == providerName);
|
|
}
|
|
|
|
string value = null;
|
|
foreach (var provider in providers)
|
|
{
|
|
value = await provider.GetOrNullAsync(
|
|
setting,
|
|
provider.Name == providerName ? providerKey : null
|
|
);
|
|
|
|
if (value != null)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (setting.IsEncrypted)
|
|
{
|
|
value = SettingEncryptionService.Decrypt(setting, value);
|
|
}
|
|
|
|
return value;
|
|
}
|
|
} |