一、AbpSettingsModule的模块的生命周期的定义
SettingOptions提供ISettingDefinitionProvider,Define(ISettingDefinitionContext context)
在模块的PreConfigureServices,只需要实现了ISettingDefinitionProvider,自动添加到设置的定义里。比如邮件设置,由SettingDefinitionManager下CreateSettingDefinitions遍历得到SettingDefinitionContext
ISettingValueProvider 提供了4个自定义的设置值的提供者,分别是默认值提供者,全局值提供者,租户值提供,用户值提供
public override void PreConfigureServices(ServiceConfigurationContext context) { AutoAddDefinitionProviders(context.Services); } public override void ConfigureServices(ServiceConfigurationContext context) { Configure<SettingOptions>(options => { options.ValueProviders.Add<DefaultValueSettingValueProvider>(); options.ValueProviders.Add<GlobalSettingValueProvider>(); options.ValueProviders.Add<TenantSettingValueProvider>(); options.ValueProviders.Add<UserSettingValueProvider>(); }); } private static void AutoAddDefinitionProviders(IServiceCollection services) { var definitionProviders = new List<Type>(); services.OnRegistred(context => { if (typeof(ISettingDefinitionProvider).IsAssignableFrom(context.ImplementationType)) { definitionProviders.Add(context.ImplementationType); } }); services.Configure<SettingOptions>(options => { options.DefinitionProviders.AddIfNotContains(definitionProviders); }); }
二、SettingProvider是主要入口,构造函数有options,serviceProvider,settingDefinitionManager,settingEncryptionService
主要为了得到属性值
public virtual async Task<string> 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(providers, setting);
//加密 if (setting.IsEncrypted) { value = SettingEncryptionService.Decrypt(setting, value); } return value; }
protected virtual async Task<string> GetOrNullValueFromProvidersAsync( IEnumerable<ISettingValueProvider> providers, SettingDefinition setting) {
//遍历对应值提供Providers,获取对应的值 foreach (var provider in providers) { var value = await provider.GetOrNullAsync(setting); if (value != null) { return value; } } return null; }
领域建模知识
1、首先确定settingdefinition配置定义,如名字,显示名字,描述,默认值,是否对客户端可显示,提供列表,用户自定义属性,是否加密
2、settingdefinitionContext上下文,提供配置的定义SettingDefinition ,存储配置字典的定义 Dictionary<string, SettingDefinition>
3、SettingDefinitionProvider提供者,定义 配置的上下文Define(ISettingDefinitionContext context)
比如邮件设置的上下文
internal class EmailSettingProvider : SettingDefinitionProvider { public override void Define(ISettingDefinitionContext context) { context.Add( new SettingDefinition(EmailSettingNames.Smtp.Host, "127.0.0.1"), new SettingDefinition(EmailSettingNames.Smtp.Port, "25"), new SettingDefinition(EmailSettingNames.Smtp.UserName), new SettingDefinition(EmailSettingNames.Smtp.Password, isEncrypted: true), new SettingDefinition(EmailSettingNames.Smtp.Domain), new SettingDefinition(EmailSettingNames.Smtp.EnableSsl, "false"), new SettingDefinition(EmailSettingNames.Smtp.UseDefaultCredentials, "true"), new SettingDefinition(EmailSettingNames.DefaultFromAddress, "[email protected]"), new SettingDefinition(EmailSettingNames.DefaultFromDisplayName, "ABP application") ); } }
4、配置值的提供者ISettingValueProvider,有多个提供者,比如
1)默认提供者,获取配置定义的值
2)全局提供者,从ISettingStore获取值,ProviderName = "Global"
3)租户提供者,从ISettingStore获取值,providerName=Tenant,providerKey=CurrentTenant.Id?.ToString()
4)用户提供者,从ISettingStore获取值,providerName=User,providerKey=CurrentUser.Id.ToString()
5、settingdefinitionManager的管理,获取到配置的定义,所有设置的定义 1)初始化所有DefinitionProviders,配置settingdefinitionContext上下文
public SettingDefinitionManager( IOptions<SettingOptions> options, IServiceProvider serviceProvider) { ServiceProvider = serviceProvider; Options = options.Value; SettingDefinitions = new Lazy<IDictionary<string, SettingDefinition>>(CreateSettingDefinitions, true); } protected virtual IDictionary<string, SettingDefinition> CreateSettingDefinitions() { var settings = new Dictionary<string, SettingDefinition>(); using (var scope = ServiceProvider.CreateScope()) { var providers = Options .DefinitionProviders .Select(p => scope.ServiceProvider.GetRequiredService(p) as ISettingDefinitionProvider) .ToList(); foreach (var provider in providers) { provider.Define(new SettingDefinitionContext(settings)); } } return settings; }