介绍
每个应用程序都需要存储一些设置,并在应用程序的某个地方使用这些设置。ABP提供了一个强大的基础设施来存储/检索在服务器端和客户端都可用的应用程序、租户和用户级别设置。
设置是通常存储在数据库(或其他数据源)中的名称-值字符串对。我们可以通过将非字符串值转换为字符串来存储它。
关于ISettingStore
为了使用设置系统,必须实现ISettingStore接口。虽然我们可以用自己的方式实现它,但它完全是在Module Zero项目中实现的。如果没有实现,则从应用程序的配置文件(web.config或者 app.config)读取设置。但这些设置无法更改。限定范围也不起作用。
定义设置
设置必须在使用前定义。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, clientVisibilityProvider: new VisibleSettingClientVisibilityProvider() ) }; } }
GetSettingDefinitions 方法返回一个SettingDefinition对象. SettingDefinition 类在它的构造函数中有一些参数:
- 名称Name (必要的): setting名称必须是系统范围内的唯一 的。尽量使用一个常量字符串,而不是一个经常变化的字符串。
- Default value: 必须有一个默认值,默认值可以是null或者空的字符串。
- Scopes: 需要定义setting的范围。
- 显示名称Display name: 一个可本地化的字符串,可用于稍后在UI中显示设置的名称。
- 描述Description: 一个可本地化的字符串,可用于稍后在UI中显示设置的描述。
- 组Group:可用于组设置。这仅用于UI,不用于设置管理。
- ClientVisibilityProvider: 可用于确定是否可以在客户端上使用设置。
- isInherited: 用于确定该设置是否由租户和用户继承(请参阅设置范围部分)。
- customData: 可用于为该设置定义设置自定义数据。
在创建setting提供程序之后,必须在模块的PreIntialize方法中注册:
Configuration.Settings.Providers.Add<MySettingProvider>();
设置提供程序通过依赖注入自动注册。设置提供程序可以注入任何依赖项(如存储库),以使用其他源构建设置定义。
设置范围(Setting scope)
在SettingScopes enum枚举中定义了三个设置范围(或级别)
- 应用程序(Application):应用程序范围设置用于独立于用户/租户的设置。例如,我们可以定义一个名为“SmtpServerAddress”的设置,以便在发送电子邮件时获取服务器的IP地址。如果该设置只有一个值(不是根据用户进行更改),那么我们可以将其定义为应用程序范围。
- 租户(Tenant):如果应用程序是多租户的,我们可以定义特定于租户的设置。
- User:我们可以使用用户范围的设置来存储/获取特定于每个用户的设置的值。
settingscope enum有一个Flags属性,因此我们可以定义一个具有多个范围的设置。
默认情况下,设置范围是分层的(除非您将继承设置为false)。例如,如果我们将一个设置的范围定义为“Application | Tenant | User”,并试图获取该设置的当前值:
•如果为用户定义(覆盖)了特定于用户的值,我们将得到该值。
•如果没有,如果它为租户定义(覆盖),我们将得到租户特定的值.
•如果没有,我们将得到定义了的应用程序值。
•如果没有,我们将得到默认值。
默认值可以是null或空字符串。建议在可能的情况下为设置提供默认值。
服务器端(Server-side)
ISettingManager
ISettingManager用于执行设置操作。我们可以在应用程序的任何地方注入并使用它。ISettingManager定义了许多方法来获取设置的值。
最常用的方法是GetSettingValue(或异步调用的GetSettingValueAsync)。它根据默认值、应用程序、租户和用户设置返回设置的当前值(如前面的设置范围一节所述)。例如:
//Getting a boolean value (async call) var value1 = await SettingManager.GetSettingValueAsync<bool>("PassiveUsersCanNotLogin"); //Getting a string value (sync call) var value2 = SettingManager.GetSettingValue("SmtpServerAddress");
如上所示,GetSettingValue有通用和异步版本,还有一些方法可以获取特定租户或用户的设置值或所有设置值的列表。
由于ISettingManager被广泛使用,一些特殊的基类(如ApplicationService、DomainService和AbpController)有一个名为SettingManager的属性。如果我们从这些类派生,就不需要显式地注入它。
ISettingDefinitionManager
ISettingDefinitionManager还可以用于获取AppSettingProvider中定义的设置定义。我们也可以在应用程序的任何地方注入并使用它。使用ISettingDefinitionManager可以获得定义名、默认值、显示名等等。
客户端
设置定义的ClientVisibilityProvider属性确定客户端设置的可见性。ISettingClientVisibilityProvider有四种实现。
- VisibleSettingClientVisibilityProvider:使设置定义对客户端可见。
- HiddenSettingClientVisibilityProvider:向客户端隐藏设置定义。
- RequiresAuthenticationSettingClientVisibilityProvider:当用户登录时,使设置定义对客户端可见。
- RequiresPermissionSettingClientVisibilityProvider:如果登录用户具有特定权限,则使设置定义对客户端可见。
如果根据设置定义的ClientVisibilityProvider的一个设置对客户端是可见的,那么您可以使用JavaScript在客户端获得它的当前值。 abp.setting命名空间定义了所需的函数和对象,例如:
var currentColor = abp.setting.get("SiteColorPreference");
还有getInt和getBoolean方法。您可以使用abp.setting.values对象获取所有值。注意,如果我们更改服务器端上的设置,客户端无法知道该更改,除非刷新页面、或以某种方式重新加载设置或通过代码手动更新设置。
改变设置
ISettingManager定义了ChangeSettingForApplicationAsync、ChangeSettingForTenantAsync和ChangeSettingForUserAsync方法(和同步版本),分别为应用程序、租户和用户更改设置。
关于缓存
设置管理器缓存设置在服务器端,因此我们不应该使用存储库或数据库更新语句直接更改设置值。