这是一种全局的提供者,它没有对应的 Key,也就是说如果数据库能查到 ProviderName 是 G 的记录,就直接返回它的值了。
public class GlobalSettingValueProvider : SettingValueProvider { public const string ProviderName = "G"; public override string Name => ProviderName; public GlobalSettingValueProvider(ISettingStore settingStore) : base(settingStore) { } public override Task<string> GetOrNullAsync(SettingDefinition setting) { return SettingStore.GetOrNullAsync(setting.Name, Name, null); } }TenantSettingValueProvider:
租户提供者,则是会将当前登录租户的 Id 结合 T 进行查询,也就是参数值是按照不同的租户进行隔离的。
public class TenantSettingValueProvider : SettingValueProvider { public const string ProviderName = "T"; public override string Name => ProviderName; protected ICurrentTenant CurrentTenant { get; } public TenantSettingValueProvider(ISettingStore settingStore, ICurrentTenant currentTenant) : base(settingStore) { CurrentTenant = currentTenant; } public override async Task<string> GetOrNullAsync(SettingDefinition setting) { return await SettingStore.GetOrNullAsync(setting.Name, Name, CurrentTenant.Id?.ToString()); } }UserSettingValueProvider:
用户提供者,则是会将当前用户的 Id 作为查询条件,结合 U 在数据库进行查询匹配的参数值,参数值是根据不同的用户进行隔离的。
public class UserSettingValueProvider : SettingValueProvider { public const string ProviderName = "U"; public override string Name => ProviderName; protected ICurrentUser CurrentUser { get; } public UserSettingValueProvider(ISettingStore settingStore, ICurrentUser currentUser) : base(settingStore) { CurrentUser = currentUser; } public override async Task<string> GetOrNullAsync(SettingDefinition setting) { if (CurrentUser.Id == null) { return null; } return await SettingStore.GetOrNullAsync(setting.Name, Name, CurrentUser.Id.ToString()); } } 2.3.3 参数值的存储除了 DefaultValueSettingValueProvider 是直接从参数定义获取值以外,其他的参数值提供者都是通过 ISettingStore 读取参数值的。在该模块的默认实现当中,是直接返回 null 的,只有当你使用了 Volo.Abp.SettingManagement 模块,你的参数值才是存储到数据库当中的。
我这里不再详细解析 Volo.Abp.SettingManagement 模块的其他实现,只说一下 ISettingStore 在它内部的实现 SettingStore。
public class SettingStore : ISettingStore, ITransientDependency { protected ISettingManagementStore ManagementStore { get; } public SettingStore(ISettingManagementStore managementStore) { ManagementStore = managementStore; } public Task<string> GetOrNullAsync(string name, string providerName, string providerKey) { return ManagementStore.GetOrNullAsync(name, providerName, providerKey); } }我们可以看到它也只是个包装,真正的操作类型是 ISettingManagementStore。
2.3.4 参数值的设置在 ABP vNext 的核心模块当中,是没有提供对参数值的变更的。只有在 Volo.Abp.SettingManagement 模块内部,它提供了 ISettingManager 管理器,可以进行参数值的变更。原理很简单,就是对数据库对应的表进行修改而已。
public async Task SetAsync(string name, string value, string providerName, string providerKey) { // 操作仓储,查询记录。 var setting = await SettingRepository.FindAsync(name, providerName, providerKey); // 新增或者更新记录。 if (setting == null) { setting = new Setting(GuidGenerator.Create(), name, value, providerName, providerKey); await SettingRepository.InsertAsync(setting); } else { setting.Value = value; await SettingRepository.UpdateAsync(setting); } } 三、总结ABP vNext 提供了多种参数值提供者,我们可以根据自己的需要灵活选择。如果不能够满足你的需求,你也可以自己实现一个参数值提供者。我建议对于用户在界面可更改的参数,都可以使用 SettingDefinition 定义成参数,可以根据不同的情况进行配置读取。
ABP vNext 其他模块用到的许多参数,也都是使用的 SettingDefinition 进行定义。例如 Identity 模块用到的密码验证规则,就是通过 ISettingProvider 进行读取的,还有当前程序的默认语言。