每个应用程序都需要存储一些设置信息,然后在应用程序中的某个地方使用这些设置。ABP提供了健壮的基础设施来存储或检索服务端和客户端的 应用程序,租户,用户 级别的可用设置。
一个设置一般是存储在数据库(或其他源)的 name-value 字符串对。我们可以将非字符串的值转换成字符串。
为了使用设置系统,必须要实现 ISettingStore 。虽然你可以用自己的方式实现,但是它已完全实现在 module-zero 中了。
一个设置使用前必须先定义。ABP是模块化设计的,因此,不同的模块可以有不同的设置。要定义一个设置,一个模块应该创建一个派生于 SettingProvider (设置提供器)的类。设置提供器的一个例子如下所示:
public class MySettingProvider : SettingProvider { public override IEnumerable<SettingDefinition> GetSettingDefinitions(SettingDefinitionProviderContext context) { return new[] { new SettingDefinition( "SmtpServerAddress", "127.0.0.1" ), new SettingDefinition( "PassiveUsersCanNotLogin", "true", scopes: SettingScopes.Application | SettingScopes.Tenant ), new SettingDefinition( "SiteColorPreference", "red", scopes: SettingScopes.User, isVisibleToClients: true ) }; } }
GetSettingDefinitions方法应该返回 SettingDefinition 集合。SettingDefinition类的构造函数有一些参数:
创建一个设置提供器之后,我们应该在模块的PreInitialize方法中注册。
Configuration.Settings.Providers.Add<MySettingProvider>();
这样,设置提供器就自动注册到依赖注入系统中了。因此,设置提供器可以使用一些其他的资源注入任何依赖(如仓储)来生成设置定义。
在 SettingScope 枚举类中定义了三种 设置范围(或者说等级) :
SettingScopes枚举类型有 Flags 特性,因此我们可以定义一个 不止一个范围 的setting。
设置范围是有层次的,比如,如果我们定义的设置范围是“Application | Tenant | User”,并尝试获取该设置 当前的值 ,那么:
默认值可能是null或者空字符串。如果可能的话,建议为setting的默认值提供默认值。
定义了一个setting之后,我们就可以在客户端和服务端获得它当前的值。
ISettingManager用于执行setting操作。我们可以在应用中的任何地方注入并使用它。ISettingManager定义了许多获取一个setting值的方法。
用的最多的方法是 GetSettingValue (或者异步调用GetSettingValueAsync)。它会返回基于默认值,应用程序,租户和用户setting的当前的值(正如上面提到的)。例如:
//获取一个bool值(异步调用) var value1 = await SettingManager.GetSettingValueAsync<bool>("PassiveUsersCanNotLogin"); //获取一个string值(同步调用) var value2 = SettingManager.GetSettingValue("SmtpServerAddress");
GetSettingValue有泛型和异步版本,如上面所示。也有获得特定租户或者用户的setting值或者所有setting值的列表的方法。
因为ISettingManager使用广泛,所以一些特殊的基类(如ApplicationService,DomainService和AbpController)就有了一个叫做 SettingManager 的属性。如果我们从这些类中派生,那么就不需要显式注入它了。
当定义一个setting时,如果将 IsVisibleToClients 设置为true,那么可以使用javascript在客户端获得当前的值。 abp.setting 命名空间定义了一些用得到的函数和对象。例如:
var currentColor = abp.setting.get("SiteColorPreference");
也有 getInt 和 getBoolean 方法。你可以使用 abp.setting.values 获得所有的值。注意:如果在服务端更改了一个setting,那么如果页面没有更新,setting没有重新加载或者通过代码手动更新的话,那么客户端就不知道该setting是否发生了变化。
ISettingManager为应用程序,租户和用户分别定义了 ChangeSettingForApplicationAsync, ChangeSettingForTenantAsync和ChangeSettingForUserAsync 方法来更改setting。
Setting Manager(管理者)缓存到了服务端的setting了。因此,我们不应该使用仓储或者数据库更新来直接更改一个setting的值。