So, you can get or set a setting value for different setting value providers (Default, Global, User, Tenant... etc).
So, you can get or set a setting value for different setting value providers (Default, Global, User, Tenant... etc).
The scoped `GetOrNull...` and `GetAll...` extension methods use fallback values by default. Pass `fallback: false` when you need only the value explicitly stored for the requested provider. Setting a value to `null` clears that provider's value.
For a non-encrypted inherited setting, setting a provider value to the same value as its fallback also clears the provider record by default. The comparison is case-insensitive. Pass `forceToSet: true` to a user- or tenant-scoped `Set...` method when you intentionally need to persist the same value as the fallback. `SetForTenantOrGlobalAsync` honors this parameter only when `tenantId` has a value; its global branch calls `SetGlobalAsync`, which does not expose the parameter. For encrypted settings, fallback-equal clearing does not apply to non-empty values because they are encrypted before comparison; an empty string can still be cleared when it equals the fallback. Pass `null` explicitly when you want to clear the provider value.
> Use the `ISettingProvider` instead of the `ISettingManager` if you only need to read the setting values, because it implements caching and supports all deployment scenarios. You can use the `ISettingManager` if you are creating a setting management UI.
> Use the `ISettingProvider` instead of the `ISettingManager` if you only need to read the setting values, because it implements caching and supports all deployment scenarios. You can use the `ISettingManager` if you are creating a setting management UI.
### Setting Cache
### Setting Cache
@ -88,9 +92,9 @@ Setting Management module is extensible, just like the [setting system](../frame
* `ConfigurationSettingManagementProvider`: Gets the value from the [IConfiguration service](../framework/fundamentals/configuration.md). It can not set the configuration value because it is not possible to change the configuration values on runtime.
* `ConfigurationSettingManagementProvider`: Gets the value from the [IConfiguration service](../framework/fundamentals/configuration.md). It can not set the configuration value because it is not possible to change the configuration values on runtime.
* `GlobalSettingManagementProvider`: Gets or sets the global (system-wide) value for a setting.
* `GlobalSettingManagementProvider`: Gets or sets the global (system-wide) value for a setting.
* `TenantSettingManagementProvider`: Gets or sets the setting value for a tenant.
* `TenantSettingManagementProvider`: Gets or sets the setting value for a tenant.
* `UserSettingManagementProvider`: Gets the setting value for a user.
* `UserSettingManagementProvider`: Gets or sets the setting value for a user.
`ISettingManager` uses the setting management providers on get/set methods. Typically, every setting management provider defines extension methods on the `ISettingManagement` service (like `SetForUserAsync` defined by the user setting management provider).
`ISettingManager` uses the setting management providers on get/set methods. Typically, every setting management provider defines extension methods on the `ISettingManager` service (like `SetForUserAsync` defined by the user setting management provider).
If you want to create your own provider, implement the `ISettingManagementProvider` interface or inherit from the `SettingManagementProvider` base class:
If you want to create your own provider, implement the `ISettingManagementProvider` interface or inherit from the `SettingManagementProvider` base class:
The order of the providers are important. Providers are executed in the reverse order. That means the `CustomSettingProvider` is executed first for this example. You can insert your provider in any order in the `Providers` list.
The order of the providers are important. Providers are executed in the reverse order. That means the `CustomSettingProvider` is executed first for this example. You can insert your provider in any order in the `Providers` list.
The module can persist setting definitions in addition to setting values. `SettingManagementOptions` controls this behavior:
* `SaveStaticSettingsToDatabase` is `true` by default. During application initialization, definitions contributed by code are synchronized with the `<DbTablePrefix>SettingDefinitions` table or collection (`AbpSettingDefinitions` by default).
* `IsDynamicSettingStoreEnabled` is `false` by default. Enable it to include persisted definitions in the setting definition store at runtime.
```csharp
Configure<SettingManagementOptions>(options =>
{
options.IsDynamicSettingStoreEnabled = true;
});
```
Both options are disabled automatically in an ABP data migration environment. Static definitions continue to come from the application's setting definition providers when the dynamic store is disabled.
## Setting Management UI
## Setting Management UI
Setting Mangement module provided the Email setting, Feature management and Timezone setting UI by default.
The MVC, Blazor and MudBlazor packages provide built-in Email and Time Zone setting groups. The Angular configuration package provides the built-in Email group. Other modules can contribute their own groups to the same page. For example, the Feature Management module contributes the Feature Management group shown below.
> You can click the Send test email button to send a test email to check your email settings.
> You can click the Send test email button to send a test email to check your email settings.
The Email group uses `IEmailSettingsAppService`. Reading and updating the settings requires the `SettingManagement.Emailing` permission. Sending a test email additionally requires `SettingManagement.Emailing.Test`. The operations are exposed under `/api/setting-management/emailing`, with the test operation at `/api/setting-management/emailing/send-test-email`.
Email operations also require the `SettingManagement.Enable` feature, which is `true` by default. For tenants, they additionally require its child feature, `SettingManagement.AllowChangingEmailSettings`, which is `false` by default. The read operation does not return the stored SMTP password. On update, a blank password leaves the existing password unchanged.
Setting it is extensible; You can add your tabs to this page for your application settings.
The Time Zone group uses `ITimeZoneSettingsAppService` and requires the `SettingManagement.TimeZone` permission. Its HTTP API is exposed at `/api/setting-management/timezone`; `GET /api/setting-management/timezone/timezones` returns the available IANA time zones. Updating the value to `Unspecified` clears the host-global or current-tenant value so the configured fallback is used.
The built-in MVC, Blazor and MudBlazor contributors add this group only when `IClock.SupportsMultipleTimezone` is `true`.
The page is extensible, so you can add groups for your application's settings.
### MVC UI
### MVC UI
@ -180,9 +204,14 @@ Create a `BookStoreSettingPageContributor.cs` file under the `Settings` folder:
The content of the file is shown below:
The content of the file is shown below:
```csharp
```csharp
public class BookStoreSettingPageContributor : ISettingPageContributor
public class BookStoreSettingPageContributor : SettingPageContributorBase
{
{
public Task ConfigureAsync(SettingPageCreationContext context)
public BookStoreSettingPageContributor()
{
RequiredPermissions("BookStore.Settings");
}
public override Task ConfigureAsync(SettingPageCreationContext context)
{
{
context.Groups.Add(
context.Groups.Add(
new SettingPageGroup(
new SettingPageGroup(
@ -195,15 +224,13 @@ public class BookStoreSettingPageContributor : ISettingPageContributor
return Task.CompletedTask;
return Task.CompletedTask;
}
}
public Task<bool> CheckPermissionsAsync(SettingPageCreationContext context)
{
// You can check the permissions here
return Task.FromResult(true);
}
}
}
```
```
Derive from `SettingPageContributorBase` instead of directly implementing `ISettingPageContributor`. Use `RequiredPermissions`, `RequiredFeatures` and `RequiredTenantSideFeatures` in the constructor to declare the conditions for the group. The module batches these checks before calling `ConfigureAsync`.
`SettingPageGroup` also accepts an optional `parameter` for the view component. Groups are ordered by `order`, then by display name.
Open the `BookStoreWebModule.cs` file and add the following code:
Open the `BookStoreWebModule.cs` file and add the following code:
```csharp
```csharp
@ -246,8 +273,13 @@ The content of the file is shown below:
```csharp
```csharp
public class BookStoreSettingComponentContributor : ISettingComponentContributor
public class BookStoreSettingComponentContributor : ISettingComponentContributor
{
{
public Task ConfigureAsync(SettingComponentCreationContext context)
public async Task ConfigureAsync(SettingComponentCreationContext context)
{
{
if (!await CheckPermissionsAsync(context))
{
return;
}
context.Groups.Add(
context.Groups.Add(
new SettingComponentGroup(
new SettingComponentGroup(
"Volo.Abp.MySettingGroup",
"Volo.Abp.MySettingGroup",
@ -256,18 +288,22 @@ public class BookStoreSettingComponentContributor : ISettingComponentContributor
order : 1
order : 1
)
)
);
);
return Task.CompletedTask;
}
}
public Task<bool> CheckPermissionsAsync(SettingComponentCreationContext context)
public async Task<bool> CheckPermissionsAsync(SettingComponentCreationContext context)
{
{
// You can check the permissions here
var authorizationService = context.ServiceProvider
The settings page calls `ConfigureAsync` for every registered contributor, while menu visibility is checked separately with `CheckPermissionsAsync`. Perform the authorization check before adding the group, as in the example, and return the same result from `CheckPermissionsAsync`.
MudBlazor provides the equivalent `ISettingComponentContributor`, `SettingComponentCreationContext`, `SettingComponentGroup` and `SettingManagementComponentOptions` types in the `Volo.Abp.SettingManagement.Blazor.MudBlazor` namespace. Use those types for a MudBlazor UI. In both Blazor UI stacks, a group accepts an optional component `parameter` and is ordered by `order`, then by display name.
Open the `BookStoreBlazorModule.cs` file and add the following code:
Open the `BookStoreBlazorModule.cs` file and add the following code:
```csharp
```csharp
@ -293,34 +329,72 @@ Create a component with the following command:
yarn ng generate component my-settings
yarn ng generate component my-settings
```
```
Open the `app.component.ts` and modify the file as shown below:
Register the module configuration and your setting tab in `app.config.ts`:
```js
```ts
import { Component, inject } from '@angular/core';
import { ApplicationConfig, inject, provideAppInitializer } from '@angular/core';
import { SettingTabsService } from '@abp/ng.setting-management/config';
import {
provideSettingManagementConfig,
SettingTabsService,
} from '@abp/ng.setting-management/config';
import { MySettingsComponent } from './my-settings/my-settings.component';
import { MySettingsComponent } from './my-settings/my-settings.component';
`provideSettingManagementConfig` registers the route, the built-in Email tab and route visibility. The Administration -> Settings route is visible only when it has at least one visible tab and the `SettingManagement.Enable` feature is enabled. A tab can use `requiredPolicy` and `invisible` to control its own visibility.
The `@abp/ng.setting-management` package exports the `SettingManagementComponent`, `createRoutes` and the `eSettingManagementComponents.SettingManagement` key. Use the key with the [component replacement system](../framework/ui/angular/component-replacement.md) when you need to replace the complete Setting Management page. `SettingManagementModule.forLazy` and `SettingManagementConfigModule.forRoot` are obsolete; use `createRoutes` and `provideSettingManagementConfig` in standalone applications.
#### Run the Application
#### Run the Application
Navigate to `/setting-management` route to see the changes:
Navigate to `/setting-management` route to see the changes:
The Entity Framework Core and MongoDB packages persist setting values and setting definition records.
### Common
`AbpSettingManagementDbProperties` exposes the common persistence configuration:
* `DbTablePrefix` is the prefix used for EF Core tables and MongoDB collections. It defaults to `AbpCommonDbProperties.DbTablePrefix`.
* `DbSchema` is the schema used by EF Core. MongoDB does not use this value.
* `ConnectionStringName` is `AbpSettingManagement`. Define this named connection string to place the module in a separate database; otherwise, it falls back to the `Default` connection string.
### Entity Framework Core
The Entity Framework Core provider maps the following tables with the default prefix:
* `AbpSettings`
* `AbpSettingDefinitions`
### MongoDB
The MongoDB provider maps the following collections with the default prefix: