Introduction

Every application need to store some settings and use these settings in somewhere in the application. ASP.NET Boilerplate provides a strong infrastructure to store/retrieve application, tenant and user level settings usable both in server and client sides.

每个应用程序都需要存储一些设置,并在应用程序的某处使用这些设置。ASP.NET样板提供了强大的基础设施来存储/检索应用程序,租户和用户级别的设置均可用的服务器和客户端。

A setting is a name-value string pair that is generally stored in a database (or another source). We can store non-string values by converting to string.

设置是一个名称值字符串对,通常存储在数据库中(或另一个源)。我们可以通过转换字符串来存储非字符串值。

About ISettingStore

ISettingStore interface must be implemented in order to use setting system. While you can implement it in your own way, it's fully implemented in module-zero project. If it's not implemented, settings are read from application's configuration file (web.config or app.config) but can not change any setting. Also, scoping will not work.

isettingstore接口必须实现为了使用系统设置。虽然可以以自己的方式实现它,但它完全在module-zero的项目中实现。如果不实施,设置是从应用程序的配置文件的读取(Web.config或应用程序配置)但不能改变任何设置。同时,范围将不工作。

Defining settings

A setting must be defined before usage. ASP.NET Boilerplate is designed to be modular. So, different modules can have different settings. A module should create a class derived from SettingProvider in order to define it's settings. An example setting provider is shown below:

设置必须在使用前定义。ASP.NET样板的设计是模块化的。因此,不同的模块可以有不同的设置。一个模块应该创建一个类的派生类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 method should return SettingDefinition objects. SettingDefinition class has some parameters in it's constructor:

  • Name (required): A setting must have a system-wide unique name. It's good idea to define a const string for a setting name instead of a magic string.
  • Default value: A setting may have a default value. This value can be null or empty string.
  • Scopes: A setting should define it's scope (see below).
  • Display name: A localizable string that can be used to show setting's name later in UI.
  • Description: A localizable string that can be used to show setting's description later in UI.
  • Group: Can be used to group settings. This is just for UI, not used in setting management.
  • IsVisibleToClients: Set true to make a setting usable on the client side.
  • isInherited: Used to set if this setting is inherited by tenant and users (See setting scope section).
  • customData: Can be used to set a custom data for this setting definition.
  • 名称(必填):设置必须具有全系统唯一名称。为一个设置名称而不是一个魔术字符串定义一个常量字符串是一个好主意。
    默认值:设置可能具有默认值。此值可以是空字符串或空字符串。
    范围:一个设置应该定义它的作用域(见下文)。
    显示名称:可本地化的字符串,可以用来显示设置的名字后来在UI。
    描述:可本地化的字符串,可以用来显示设置的描述后来在UI。
    组:可用于组设置。这只是用于UI,而不是用于设置管理。
    对客户端可见:使设置可用的客户端。
    来源:用来设置如果设置是由承租人和用户继承(见设置范围部分)。
    自定义数据:可以用于此设置定义设置自定义数据。

After creating a setting provider, we should register it in PreIntialize method of our module:

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

Setting providers are registered to dependency injection automatically. So, a setting provider can inject any dependency (like a repository) to build setting definitions using some other sources.

设置提供者自动注册为依赖注入。因此,设置提供程序可以注入任何依赖项(如存储库)以使用其他源构建设置定义。

Setting scope

There are three setting scopes (or levels) defined in SettingScopes enum:

  • Application: An application scoped setting is used for user/tenant independed settings. For example, we can define a setting named "SmtpServerAddress" to get server's IP address when sending emails. If this setting has a single value (not changes based on users), then we can define it as Application scoped.
  • Tenant: If the application is multi-tenant, we can define tenant-specific settings.
  • User: We can use a user scoped setting to store/get value of the setting specific to each user.
  • 应用范围:应用范围设置用于用户/租户独立设置。例如,我们可以定义一个名为“smtpserveraddress”获得服务器的IP地址发送邮件时。如果此设置一个值(不改变基于用户),那么我们可以把它定义为应用程序范围。
    租户:如果应用程序是多租户,我们可以定义特定于租户的设置。
    用户:我们可以用一个用户范围的设置存储到设置特定于每个用户的价值。

SettingScopes enum has Flags attribute, so we can define a setting with more than one scopes.

Setting scope is hierarchic by default (unless you set isInherited to false). For example, if we define a setting's scope as "Application | Tenant | User" and try to get current value of the the setting;

  • We get the user-specific value if it's defined (overrided) for the user.
  • If not, we get the tenant-specific value if it's defined (overrided) for the tenant.
  • If not, we get the application value if it's defined.
  • If not, we get the default value.

Default value can be null or empty string. It's adviced to provide default values for settings where it's possible.

Overriding Setting Definitions(重写设置定义)

context.Manager can be used to get a setting definition to change it's values. In this way, you can manipulate setting definitions of depended modules.

Getting setting values

After defining a setting, we can get it's current value both in server and client.

Server side

ISettingManager is used to perform setting operations. We can inject and use it anywhere in the application. ISettingManager defines many methods to get a setting's value.

Most used method is GetSettingValue (or GetSettingValueAsync for async call). It returns current value of the setting based on default value, application, tenant and user settings (as described in Setting scope section before). Examples:

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 has generic and async versions as shown above. There are also methods to get a specific tenant or user's setting value or list of all setting values.

Since ISettingManager is widely used, some special base classes (like ApplicationService, DomainService and AbpController) has a property named SettingManager. If we derived from these classes, no need to explicitly inject it.

getsettingvalue具有通用的异步版本,如上图所示。还有一些方法可以获得特定的租户或用户的设置值或所有设置值的列表。

自从ISettingManager被广泛使用,一些特殊的基类(如应用服务,按和AbpController)有一个属性叫settingmanager。如果我们从这些类派生,不需要显式地注入它。

Client side

If you set IsVisibleToClients as true while defining a setting, then you can get it's current value in the client side using javascript. abp.setting namespace defines needed functions and objects. Example:

var currentColor = abp.setting.get("SiteColorPreference");

There is also getInt and getBoolean methods. You can get all values using abp.setting.values object. Note that; If you change a setting in server side, clienct can not know this change unless page is refreshed, settings are somehow reloaded or it's manually updated by code.

因此,有getboolean GetInt的和方法。你可以得到所有的abp.setting.values对象的值使用。注意,如果你更改一个设置在服务器端,需要变更,除非专门clienct CAN这是refreshed设置页,它是不知何故重装或手动更新的代码。

Changing settings

ISettingManager defines ChangeSettingForApplicationAsync, ChangeSettingForTenantAsync and ChangeSettingForUserAsync methods (and sync versions) to change settings for the application, for a tenant and for a user respectively.

isettingmanager定义changesettingforapplicationasync,ChangeSettingForTenantAsync和ChangeSettingForUserAsync的方法(和同步版本)更改应用程序设置,为租户和用户分别。

About caching

Setting Manager caches settings on the server side. So, we should not directly change a setting value using repository or database update query.

设置管理器缓存服务器端的设置。因此,我们不应该直接使用存储库或数据库更新查询更改设置值。

ABP框架系列之四十六:(Setting-Management-设置管理)的更多相关文章

  1. ABP框架系列之四十九:(Startup-Configuration-启动配置)

    ASP.NET Boilerplate provides an infrastructure and a model to configure it and modules on startup. A ...

  2. ABP框架系列之三十六:(MVC-Views-MVC视图)

    Introduction ASP.NET Boilerplate is integrated to MVC Views via Abp.Web.Mvc nuget package. You can c ...

  3. ABP框架系列之四十四:(OWIN)

    If you are using both of ASP.NET MVC and ASP.NET Web API in your application, you need to add Abp.Ow ...

  4. ABP框架系列之四十二:(Object-To-Object-Mapping-对象映射)

    Introduction It's a common to map a similar object to another object. It's also tedious and repeatin ...

  5. ABP框架系列之四十八:(Specifications-规范)

    Introduction Specification pattern is a particular software design pattern, whereby business rules c ...

  6. ABP框架系列之四十五:(Quartz-Integration-Quartz-集成)

    Introduction Quartz is a is a full-featured, open source job scheduling system that can be used from ...

  7. ABP框架系列之四十:(Notification-System-通知系统)

    Introduction Notifications are used to inform users on specific events in the system. ASP.NET Boiler ...

  8. ABP框架系列之十六:(Dapper-Integration-Dapper集成)

    Introduction Dapper is an object-relational mapper (ORM) for .NET. Abp.Dapper package simply integra ...

  9. ABP框架系列之三十四:(Multi-Tenancy-多租户)

    What Is Multi Tenancy? "Software Multitenancy refers to a software architecture in which a sing ...

随机推荐

  1. HTML5 使用小结

    1.html5新增的常用元素 (a) <article.../>代表独立完整的一遍文章 (b)<section.../>对页面内容进行分块 (c)<nav.../> ...

  2. JS购物车编辑

    实现了:第一件商品的加减实现了:全选/全不选(使用prop而不是attr)实现了:删除(遮罩层) 未实现:第二件商品的删除未实现:小计及应付款额的初始化(写死的) 计算小数乘法时,要先乘100 < ...

  3. mysql5.7.18.1修改用户密码报错ERROR 1054 (42S22): Unknown column 'password' in 'field list'解决办法

    本意向修改一个用户的密码,网上搜到的命令为如下 mysql> update user set password=password(“新密码”) where user=”用户名”; 执行后报错 E ...

  4. 【Python】pip国内安装源和yum恢复

    豆瓣安装源 pip install packages -i http://pypi.doubanio.com/simple --upgrade --trusted-host pypi.doubanio ...

  5. 收藏 —— KVM网络虚拟化

    http://www.cnblogs.com/CloudMan6/p/5240770.html http://www.cnblogs.com/CloudMan6/p/5289590.html

  6. LVM逻辑卷疑问?

    创建完逻辑卷后,删除以/dev/vdb1和/dev/vdb2为基础的分区后,逻辑卷依然生效???

  7. __iter__ 和 __next__

    class F: def __init__(self,x): self.x = x def __iter__(self): #把对象 变成可迭代对象 return self def __next__( ...

  8. Django之model联表:一对多、跨表操作,联表查询

    表结构概述 model.py : class Something(models.Model): name = models.CharField(max_length=32) class UserTyp ...

  9. 什么是PLI?

    首先,什么是PLI? 本部分设定了隐藏,您已回复过了,以下是隐藏的内容 PLI 就是product liability insurance 的简写,中文可以翻译成“产品责任险”说白了,就是你的产品如果 ...

  10. object references an unsaved transient instance save the transient instance before flushing

    object references an unsaved transient instance save the transient instance before flushing 对象引用未保存的 ...