在abp中添加系統設置,都是在模塊的預初始化方法中添加的.緩存
Configuration.Settings.Providers.Add<EmailSettingProvider>();
Configuration以前已經說過了,這是AbpModule裏的屬性,IAbpStartupConfiguration 這個類就是負責abp啓動時的配置,以及模塊的配置。以前說的模塊配置是經過IAbpStartupConfiguration裏的ModuleConfigurations Modules配置的.app
public interface IAbpStartupConfiguration : IDictionaryBasedConfig { // 其餘代碼略 IModuleConfigurations Modules { get; } ISettingsConfiguration Settings { get; } // 略。 }
初始化的話,以前也說過了,是在AbpBootstrapper中,經過ioc容器取得AbpStartupConfiguration。而後執行初始化方法.在初始化方法中經過ioc容器取得每一個屬性的對應實例,賦值。也就是說 Settings就是這時候被初始化的async
public interface ISettingsConfiguration { /// <summary> /// List of settings providers. /// </summary> ITypeList<SettingProvider> Providers { get; } } internal class SettingsConfiguration : ISettingsConfiguration { public ITypeList<SettingProvider> Providers { get; private set; } public SettingsConfiguration() { Providers = new TypeList<SettingProvider>(); } }
經過看到詳細代碼,這個就很明顯了,這裏維護了一個 SettingProvider 集合
開頭能夠看到就是經過這個集合添加咱們自定義設置的,這裏集合的類型是一個SettingProvider
也就是說咱們自定義的設置,必須繼承自SettringProvider才能夠被添加ide
/// Inherit this class to define settings for a module/application. /// </summary> public abstract class SettingProvider : ITransientDependency { /// <summary> /// Gets all setting definitions provided by this provider. /// </summary> /// <returns>List of settings</returns> public abstract IEnumerable<SettingDefinition> GetSettingDefinitions(SettingDefinitionProviderContext context); }
這是一個抽象類也就是說咱們自定義的settingprovier必須實現GetSettingDefinitions方法咯.
例如,清除緩存的設置this
public class ClearCacheSettingProvider : SettingProvider { public override IEnumerable<SettingDefinition> GetSettingDefinitions(SettingDefinitionProviderContext context) { return new[] { new SettingDefinition(ClearCacheSettingNames.Password, "123qweasdZXC") }; } }
那麼SettingDefinition是什麼呢
看名字是設置的定義的意思,設置用於配置和更改應用程序的行爲 裏面有Name,DisplayName Scopes等屬性.
那麼咱們定義好了SettingProvider,在模塊與初始化方法中加入到咱們的Providers集合以後.又作了什麼呢.spa
若是你熟悉ABP的話,你就會知道,咱們把一個配置存入了集合中,那確定也要是能夠取出來的
咱們在寫代碼的時候,都是經過SettingManager
來獲取配置的.code
//Getting a boolean value (async call) var value1 = await SettingManager.GetSettingValueAsync<bool>("PassiveUsersCanNotLogin");
public class SettingManager : ISettingManager, ISingletonDependency { // 其餘代碼 略. private readonly ISettingDefinitionManager _settingDefinitionManager; }
SettingManager中有個ISettingDefinitionManager,其實 GetSettingValue方法最終調用的是settingDefinitionManager的GetSettingDefinition方法繼承
private async Task<string> GetSettingValueInternalAsync(string name, int? tenantId = null, long? userId = null, bool fallbackToDefault = true) { var settingDefinition = _settingDefinitionManager.GetSettingDefinition(name); }
接下來看看SettingDefinitionManagerget
internal class SettingDefinitionManager : ISettingDefinitionManager, ISingletonDependency { private readonly IIocManager _iocManager; private readonly ISettingsConfiguration _settingsConfiguration; private readonly IDictionary<string, SettingDefinition> _settings; /// <summary> /// Constructor. /// </summary> public SettingDefinitionManager(IIocManager iocManager, ISettingsConfiguration settingsConfiguration) { _iocManager = iocManager; _settingsConfiguration = settingsConfiguration; _settings = new Dictionary<string, SettingDefinition>(); } public void Initialize() { var context = new SettingDefinitionProviderContext(this); foreach (var providerType in _settingsConfiguration.Providers) { using (var provider = CreateProvider(providerType)) { foreach (var settings in provider.Object.GetSettingDefinitions(context)) { _settings[settings.Name] = settings; } } } } public SettingDefinition GetSettingDefinition(string name) { if (!_settings.TryGetValue(name, out var settingDefinition)) { throw new AbpException("There is no setting defined with name: " + name); } return settingDefinition; } }
能夠看到這裏維護了一個 字典,key是string,value是SettingDefinition,那麼是何時加入到字典中的呢?
能夠看到在initialize方法中遍歷咱們SettingConfiguration的Providers屬性,而後從IOC容器中取出,追加進字典集合中。那麼想知道是何時執行的,只須要看看Initialize方法的調用就知道了。
嗯,只有一個調用。就是在AbpKernelModule中 初始化完成方法中 執行的string
public sealed class AbpKernelModule { public override void PostInitialize() { // 其餘代碼.. 略 IocManager.Resolve<SettingDefinitionManager>().Initialize(); // 略。 } }