311 lines
9.9 KiB
C#
311 lines
9.9 KiB
C#
using System;
|
|
using System.Threading.Tasks;
|
|
using Furion.DependencyInjection;
|
|
using SqlSugar;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore.Query.Internal;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Options;
|
|
|
|
namespace Waste.Domain
|
|
{
|
|
public class JT_Setting
|
|
{
|
|
public JT_Setting() { }
|
|
public JT_Setting(Guid id, string name, string value, string providerName, string providerKey)
|
|
{
|
|
this.Id = id;
|
|
this.Name = name;
|
|
this.Value = value;
|
|
this.ProviderName = providerName;
|
|
this.ProviderKey = providerKey;
|
|
}
|
|
[SugarColumn(IsPrimaryKey = true)]
|
|
public Guid Id { get; set; }
|
|
public string Name { get; set; }
|
|
public string Value { get; set; }
|
|
|
|
public string ProviderName { get; set; }
|
|
public string ProviderKey { get; set; }
|
|
|
|
public override string ToString()
|
|
{
|
|
return $"{base.ToString()}, Name = {Name}, Value = {Value}, ProviderName = {ProviderName}, ProviderKey = {ProviderKey}";
|
|
}
|
|
}
|
|
public class SettingProvider : ITransient
|
|
{
|
|
private readonly IServiceProvider _serviceProvider;
|
|
|
|
private readonly SettingDefinitionManager SettingDefinitionManager;
|
|
private readonly SettingValueProviderManager SettingValueProviderManager;
|
|
|
|
|
|
public SettingProvider(IServiceProvider serviceProvider, SettingDefinitionManager settingDefinitionManager, SettingValueProviderManager settingValueProviderManager)
|
|
{
|
|
_serviceProvider = serviceProvider;
|
|
SettingDefinitionManager = settingDefinitionManager;
|
|
SettingValueProviderManager = settingValueProviderManager;
|
|
}
|
|
|
|
public virtual async Task<string?> GetOrNullAsync(string name)
|
|
{
|
|
var setting = await SettingDefinitionManager.GetAsync(name);
|
|
var providers = Enumerable
|
|
.Reverse(SettingValueProviderManager.Providers);
|
|
|
|
if (setting.Providers.Any())
|
|
{
|
|
providers = providers.Where(p => setting.Providers.Contains(p.Name));
|
|
}
|
|
|
|
//TODO: How to implement setting.IsInherited?
|
|
|
|
var value = await GetOrNullValueFromProvidersAsync(providers, setting);
|
|
/* if (value != null && setting.IsEncrypted)
|
|
{
|
|
value = SettingEncryptionService.Decrypt(setting, value);
|
|
}*/
|
|
|
|
return value;
|
|
}
|
|
|
|
|
|
|
|
protected virtual async Task<string?> GetOrNullValueFromProvidersAsync(
|
|
IEnumerable<SettingValueProvider> providers,
|
|
SettingDefinition setting)
|
|
{
|
|
foreach (var provider in providers)
|
|
{
|
|
var value = await provider.GetOrNullAsync(setting);
|
|
if (value != null)
|
|
{
|
|
return value;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public class SettingDefinitionManager : ISingleton
|
|
{
|
|
protected IDictionary<string, SettingDefinition> SettingDefinitions { get; } =
|
|
new Dictionary<string, SettingDefinition>();
|
|
|
|
public SettingDefinitionManager AddSettingDefinition(SettingDefinition settingDefinition)
|
|
{
|
|
SettingDefinitions[settingDefinition.Name] = settingDefinition;
|
|
return this;
|
|
}
|
|
public virtual async Task<SettingDefinition> GetAsync(string name)
|
|
{
|
|
|
|
var setting = await GetOrNullAsync(name);
|
|
|
|
if (setting == null)
|
|
{
|
|
throw new Exception("Undefined setting: " + name);
|
|
}
|
|
|
|
return setting;
|
|
}
|
|
public virtual Task<SettingDefinition?> GetOrNullAsync(string name)
|
|
{
|
|
return Task.FromResult(GetOrDefault(SettingDefinitions, name));
|
|
}
|
|
public static TValue? GetOrDefault<TKey, TValue>(IDictionary<TKey, TValue> dictionary, TKey key)
|
|
{
|
|
return dictionary.TryGetValue(key, out var obj) ? obj : default;
|
|
}
|
|
}
|
|
|
|
public class SettingValueProviderManager : ISingleton
|
|
{
|
|
public List<SettingValueProvider> Providers => _lazyProviders.Value;
|
|
private readonly Lazy<List<SettingValueProvider>> _lazyProviders;
|
|
protected IServiceProvider ServiceProvider { get; }
|
|
public SettingValueProviderManager(IServiceProvider serviceProvider)
|
|
{
|
|
ServiceProvider = serviceProvider;
|
|
_lazyProviders = new Lazy<List<SettingValueProvider>>(GetProviders, true);
|
|
}
|
|
|
|
|
|
|
|
protected virtual List<SettingValueProvider> GetProviders()
|
|
{
|
|
|
|
using (var scope = ServiceProvider.CreateScope())
|
|
|
|
return new List<SettingValueProvider>()
|
|
{
|
|
scope.ServiceProvider.GetRequiredService<DefaultValueSettingValueProvider>(),
|
|
scope.ServiceProvider.GetRequiredService<GlobalSettingValueProvider>(),
|
|
scope.ServiceProvider.GetRequiredService<UserSettingValueProvider>(),
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
public class SettingManagementStore : ITransient
|
|
{
|
|
private readonly ISqlSugarRepository<JT_Setting> repository;
|
|
|
|
public SettingManagementStore(ISqlSugarRepository<JT_Setting> repository)
|
|
{
|
|
this.repository = repository;
|
|
}
|
|
|
|
public virtual async Task<string> GetOrNullAsync(string name, string providerName, string providerKey)
|
|
{
|
|
return (await FindAsync(name, providerName, providerKey))?.Value;
|
|
}
|
|
public virtual async Task SetAsync(string name, string value, string providerName, string providerKey)
|
|
{
|
|
var setting = await FindAsync(name, providerName, providerKey);
|
|
if (setting == null)
|
|
{
|
|
setting = new JT_Setting(Guid.NewGuid(), name, value, providerName, providerKey);
|
|
await repository.InsertAsync(setting);
|
|
}
|
|
else
|
|
{
|
|
setting.Value = value;
|
|
await repository.UpdateAsync(setting);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
private async Task<JT_Setting> FindAsync(string name, string providerName, string providerKey)
|
|
{
|
|
return await repository.Where(x =>
|
|
x.Name == name && x.ProviderName == providerName)
|
|
.WhereIF(!string.IsNullOrWhiteSpace(providerKey), x => x.ProviderKey == providerKey).FirstAsync();
|
|
}
|
|
}
|
|
|
|
public abstract class SettingValueProvider : ITransient
|
|
{
|
|
public abstract string Name { get; }
|
|
|
|
protected SettingManagementStore SettingStore { get; }
|
|
|
|
protected SettingValueProvider(SettingManagementStore settingStore)
|
|
{
|
|
SettingStore = settingStore;
|
|
}
|
|
public abstract Task<string?> GetOrNullAsync(SettingDefinition setting);
|
|
|
|
protected virtual async Task SetAsync(string name, string value, string providerKey)
|
|
{
|
|
await SettingStore.SetAsync(name, value, Name, providerKey);
|
|
|
|
}
|
|
|
|
protected virtual async Task SetAsync(SettingDefinition setting, string value, string providerKey)
|
|
{
|
|
await SettingStore.SetAsync(setting.Name, value, Name, providerKey);
|
|
}
|
|
|
|
}
|
|
|
|
public class GlobalSettingValueProvider : SettingValueProvider
|
|
{
|
|
public GlobalSettingValueProvider(SettingManagementStore settingStore) : base(settingStore)
|
|
{
|
|
}
|
|
|
|
public const string ProviderName = "G";
|
|
|
|
public override string Name => ProviderName;
|
|
|
|
public override Task<string> GetOrNullAsync(SettingDefinition setting)
|
|
{
|
|
return SettingStore.GetOrNullAsync(setting.Name, Name, null);
|
|
}
|
|
public Task SetAsync(string name, string value)
|
|
{
|
|
return base.SetAsync(name, value, null);
|
|
}
|
|
}
|
|
public class UserSettingValueProvider : SettingValueProvider
|
|
{
|
|
public const string ProviderName = "U";
|
|
|
|
public override string Name => ProviderName;
|
|
|
|
protected ICurrentUser CurrentUser { get; }
|
|
|
|
public UserSettingValueProvider(SettingManagementStore settingStore, ICurrentUser currentUser)
|
|
: base(settingStore)
|
|
{
|
|
CurrentUser = currentUser;
|
|
}
|
|
|
|
public override async Task<string?> GetOrNullAsync(SettingDefinition setting)
|
|
{
|
|
if (CurrentUser.Id == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return await SettingStore.GetOrNullAsync(setting.Name, Name, CurrentUser.Id.ToString());
|
|
}
|
|
|
|
public Task SetAsync(string name, string value)
|
|
{
|
|
return base.SetAsync(name, value, CurrentUser.Id.ToString());
|
|
}
|
|
}
|
|
|
|
public interface ICurrentUser
|
|
{
|
|
Guid? Id { get; }
|
|
}
|
|
public class DefaultValueSettingValueProvider : SettingValueProvider
|
|
{
|
|
public const string ProviderName = "D";
|
|
|
|
public override string Name => ProviderName;
|
|
|
|
public DefaultValueSettingValueProvider(SettingManagementStore settingStore)
|
|
: base(settingStore)
|
|
{
|
|
|
|
}
|
|
|
|
public override Task<string?> GetOrNullAsync(SettingDefinition setting)
|
|
{
|
|
return Task.FromResult(setting.DefaultValue);
|
|
}
|
|
|
|
|
|
}
|
|
// public Guid UserId { get; set; }
|
|
|
|
public class SettingDefinition
|
|
{
|
|
/// <summary>
|
|
/// Unique name of the setting.
|
|
/// </summary>
|
|
[NotNull]
|
|
public string Name { get; set; }
|
|
|
|
public string DisplayName { get; set; }
|
|
|
|
/// <summary>
|
|
/// Default value of the setting.
|
|
/// </summary>
|
|
public string? DefaultValue { get; set; }
|
|
/// <summary>
|
|
/// A list of allowed providers to get/set value of this setting.
|
|
/// An empty list indicates that all providers are allowed.
|
|
/// </summary>
|
|
public List<string> Providers { get; } = new List<string>();
|
|
}
|
|
} |