zoukankan      html  css  js  c++  java
  • ABP系统设置

    代码分析

    在abp中添加系统设置,都是在模块的预初始化方法中添加的.

     Configuration.Settings.Providers.Add<EmailSettingProvider>();
    

    Configuration之前已经说过了,这是AbpModule里的属性,IAbpStartupConfiguration 这个类就是负责abp启动时的配置,以及模块的配置。之前说的模块配置是通过IAbpStartupConfiguration里的ModuleConfigurations Modules配置的.

    public interface IAbpStartupConfiguration : IDictionaryBasedConfig
    {
        //  其他代码略
        IModuleConfigurations Modules { get; }
        ISettingsConfiguration Settings { get; }
        // 略。
    }
    

    初始化的话,之前也说过了,是在AbpBootstrapper中,通过ioc容器取得AbpStartupConfiguration。然后执行初始化方法.在初始化方法中通过ioc容器取得每个属性的对应实例,赋值。也就是说 Settings就是这时候被初始化的

    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才可以被添加

    /// 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方法咯.
    例如,清除缓存的设置

    public class ClearCacheSettingProvider : SettingProvider
    {
        public override IEnumerable<SettingDefinition> GetSettingDefinitions(SettingDefinitionProviderContext context)
        {
            return new[]
            {
                new SettingDefinition(ClearCacheSettingNames.Password, "123qweasdZXC")
            };
        }
    }
    

    那么SettingDefinition是什么呢
    看名字是设置的定义的意思,设置用于配置和更改应用程序的行为 里面有Name,DisplayName Scopes等属性.
    那么我们定义好了SettingProvider,在模块与初始化方法中加入到我们的Providers集合之后.又做了什么呢.

    SettingDefinitionManager

    如果你熟悉ABP的话,你就会知道,我们把一个配置存入了集合中,那肯定也要是可以取出来的
    我们在写代码的时候,都是通过SettingManager来获取配置的.

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

    接下来看看SettingDefinitionManager

    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中 初始化完成方法中 执行的

    public sealed class AbpKernelModule
    {
        public override void PostInitialize()
        {
            //  其他代码.. 略
            IocManager.Resolve<SettingDefinitionManager>().Initialize();
            //  略。
        }
    }
    
  • 相关阅读:
    git ignore 添加忽略文件
    python| 闭包函数及装饰器
    python | DRF 框架知识总览
    python | CHROME底层原理和HTTP协议
    python| css 背景图片虚化效果
    python | js 图片与base64互相转换
    python | Linux各目录及每个目录的详细介绍
    python | 解决Django+Vue前后端分离的跨域问题及关闭csrf验证
    python | Nginx负载均衡策略
    python | Linux 搭建Nginx+uWSGI+Django环境
  • 原文地址:https://www.cnblogs.com/zzqvq/p/10341719.html
Copyright © 2011-2022 走看看