Waste/Waste.Domain/DataModel/JT_Setting.cs

311 lines
9.9 KiB
C#
Raw Normal View History

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>();
}
}