[Abp vNext 源码分析] - 11. 用户的自定义参数与配置 (2)

上面的参数定义值得注意的就是 DefaultValue 、IsVisibleToClients、IsEncrypted 这三个属性。默认值一般适用于某些系统配置,例如当前系统的默认语言。后面两个属性则更加注重于 安全问题,因为某些参数存储的是一些重要信息,这个时候就需要进行特殊处理了。

如果参数值是加密的,那么在获取参数值的时候就会进行解密操作,例如下面的代码。

SettingProvider 类中的相关代码:

// ... public class SettingProvider : ISettingProvider, ITransientDependency { // ... public virtual async Task<string> GetOrNullAsync(string name) { // ... var value = await GetOrNullValueFromProvidersAsync(providers, setting); // 对值进行解密处理。 if (setting.IsEncrypted) { value = SettingEncryptionService.Decrypt(setting, value); } return value; } // ... }

参数不对客户端可见的话,在默认的 AbpApplicationConfigurationAppService 服务类中,获取参数值的时候就会跳过。

private async Task<ApplicationSettingConfigurationDto> GetSettingConfigAsync() { var result = new ApplicationSettingConfigurationDto { Values = new Dictionary<string, string>() }; foreach (var settingDefinition in _settingDefinitionManager.GetAll()) { // 不会展示这些属性为 False 的参数。 if (!settingDefinition.IsVisibleToClients) { continue; } result.Values[settingDefinition.Name] = await _settingProvider.GetOrNullAsync(settingDefinition.Name); } return result; } 2.2.2 参数定义的扫描

跟权限定义类似,所有的参数定义都被放在了 SettingDefinitionProvider 里面,如果你需要定义一堆参数,只需要继承并实现 Define(ISettingDefinitionContext) 抽象方法就可以了。

public class TestSettingDefinitionProvider : SettingDefinitionProvider { public override void Define(ISettingDefinitionContext context) { context.Add( new SettingDefinition(TestSettingNames.TestSettingWithoutDefaultValue), new SettingDefinition(TestSettingNames.TestSettingWithDefaultValue, "default-value"), new SettingDefinition(TestSettingNames.TestSettingEncrypted, isEncrypted: true) ); } }

因为我们的 SettingDefinitionProvider 实现了 ISettingDefinitionProvider 和 ITransientDependency 接口,所以这些 Provider 都会在组件注册的时候(模块里面有定义),添加到对应的 AbpSettingOptions 内部,方便后续进行调用。

2.2.3 参数定义的管理

我们的 参数定义提供者参数值提供者 都赋值给 AbpSettingOptions 了,首先看有哪些地方使用到了 参数定义提供者

[Abp vNext 源码分析] - 11. 用户的自定义参数与配置

第二个我们已经看过,是在模块启动时有用到。第一个则是有一个 SettingDefinitionManager ,顾名思义就是管理所有的 SettingDefinition 的管理器。这个管理器提供了三个方法,都是针对 SettingDefinition 的查询功能。

public interface ISettingDefinitionManager { // 根据参数定义的标识查询,不存在则抛出 AbpException 异常。 [NotNull] SettingDefinition Get([NotNull] string name); // 获得所有的参数定义。 IReadOnlyList<SettingDefinition> GetAll(); // 根据参数定义的标识查询,如果不存在则返回 null。 SettingDefinition GetOrNull(string name); }

接下来我们看一下它的默认实现 SettingDefinitionManager ,它的内部没什么说的,只是注意 SettingDefinitions 的填充方式,这里使用了线程安全的 懒加载模式。只有当用到的时候,才会调用 CreateSettingDefinitions() 方法填充数据。

public class SettingDefinitionManager : ISettingDefinitionManager, ISingletonDependency { protected Lazy<IDictionary<string, SettingDefinition>> SettingDefinitions { get; } protected AbpSettingOptions Options { get; } protected IServiceProvider ServiceProvider { get; } public SettingDefinitionManager( IOptions<AbpSettingOptions> options, IServiceProvider serviceProvider) { ServiceProvider = serviceProvider; Options = options.Value; // 填充的时候,调用 CreateSettingDefinitions 方法进行填充。 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()) { // 从 Options 中得到类型,然后通过 IoC 进行实例化。 var providers = Options .DefinitionProviders .Select(p => scope.ServiceProvider.GetRequiredService(p) as ISettingDefinitionProvider) .ToList(); // 执行每个 Provider 的 Define 方法填充数据。 foreach (var provider in providers) { provider.Define(new SettingDefinitionContext(settings)); } } return settings; } } 2.3 参数值的管理

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsxxwj.html