First, the definition of the life cycle of the module AbpSettingsModule
SettingOptions提供ISettingDefinitionProvider,Define(ISettingDefinitionContext context)
In PreConfigureServices module, only we need to implement the ISettingDefinitionProvider, automatically added to the definition set in. Such as mail settings, the traversal SettingDefinitionManager CreateSettingDefinitions obtained SettingDefinitionContext
ISettingValueProvider provides four values provided from the provider defined, respectively, is the default provider, the global value of the provider, providing the tenants value, the user provides values
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); }); }
Two, SettingProvider main entrance, with a constructor options, serviceProvider, settingDefinitionManager, settingEncryptionService
In order to obtain a main property value
public virtual async Task<string> GetOrNullAsync(string name) {
// Get property value 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) {
// iterate provide corresponding values Providers, obtaining a value corresponding to foreach (var provider in providers) { var value = await provider.GetOrNullAsync(setting); if (value != null) { return value; } } return null; }
Domain modeling knowledge
1, first determine settingdefinition configuration definition, as the name, a display name, description, default values, whether the client can display, provide a list, user-defined properties, whether or not encrypted
2, settingdefinitionContext context, provide definitions SettingDefinition configuration, storage configuration dictionary definitions Dictionary <string, SettingDefinition>
3, SettingDefinitionProvider provider, defining the configuration context Define (ISettingDefinitionContext context)
For example, in the context of mail settings
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, the provider configuration values ISettingValueProvider, a plurality of providers, such as
1) Default provider, obtaining the configuration defined
2) global provider, obtain the value, ProviderName = "Global" from ISettingStore
3) tenants who get the value, providerName = Tenant, providerKey = CurrentTenant.Id from ISettingStore? .ToString ()
4) users who obtain the value from ISettingStore, providerName = User, providerKey = CurrentUser.Id.ToString ()
5, settingdefinitionManager management, access to the configuration definitions define all settings 1) initializes all DefinitionProviders, the context configuration settingdefinitionContext
public SettingDefinitionManager( IOptions<SettingOptions> options, IServiceProvider service) { ServiceProvider = service provider; 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; }