ABP系統設置

代碼分析

在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

ISettingsConfiguration

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

SettingDefinitionManager

若是你熟悉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();
        //  略。
    }
}
相關文章
相關標籤/搜索