The Feature Management module implements the `IFeatureManagementStore` interface defined by the [Feature System](../framework/infrastructure/features.md).
The Feature Management module persists feature values and implements the `IFeatureStore` interface defined by the [Feature System](../framework/infrastructure/features.md). It also provides management services and reusable user interfaces for reading, changing and resetting values for a feature provider.
> This document covers only the feature management module which persists feature values to a database. See [the features](../framework/infrastructure/features.md) document for more about the feature system.
@ -33,9 +33,97 @@ When you click *Actions* -> *Features* for a tenant, the feature management dial
In this dialog, you can enable, disable or set values for the features for a tenant.
### Host Feature Management
The MVC, Blazor and MudBlazor packages add a **Feature Management** group to the Setting Management page. The group is available on the host side to users granted the `FeatureManagement.ManageHostFeatures` permission. It opens the same reusable dialog with the tenant provider (`T`) and an empty provider key, which represents host feature values.
For Angular applications, register the setting-tab contributor in the application configuration:
````ts
import { ApplicationConfig } from '@angular/core';
import { provideFeatureManagementConfig } from '@abp/ng.feature-management';
export const appConfig: ApplicationConfig = {
providers: [provideFeatureManagementConfig()],
};
````
`provideFeatureManagementConfig` adds the host Feature Management tab to Setting Management and protects it with the same `FeatureManagement.ManageHostFeatures` policy. The current application templates already register this provider.
### Reusing the Feature Management Dialog
All UI implementations accept a provider name and an optional provider key. The built-in provider names are `D` for default values, `C` for configuration values, `E` for editions and `T` for tenants. Default and configuration values are read-only, while edition, tenant and custom providers can persist values.
#### MVC
Create an `abp.ModalManager` for the module page and pass the provider information when opening it:
````js
const featureManagementModal = new abp.ModalManager(
For a MudBlazor application, use the `Volo.Abp.FeatureManagement.Blazor.MudBlazor.Components` namespace. The component has the same `OpenAsync(providerName, providerKey, providerKeyDisplayName)` contract.
#### Angular
`FeatureManagementComponent` is a standalone component exported from `@abp/ng.feature-management`:
````ts
import { Component, signal } from '@angular/core';
import { FeatureManagementComponent } from '@abp/ng.feature-management';
@Component({
selector: 'app-tenant-features',
imports: [FeatureManagementComponent],
templateUrl: './tenant-features.component.html',
})
export class TenantFeaturesComponent {
readonly visible = signal(false);
tenantId = '';
}
````
````html
<abp-feature-management
[visible]="visible()"
(visibleChange)="visible.set($event)"
providerName="T"
[providerKey]="tenantId"
/>
````
Use `eFeatureManagementComponents.FeatureManagement` as the component key when replacing the dialog through the Angular component replacement system.
## IFeatureManager
`IFeatureManager` is the main service provided by this module. It is used to read and change the setting values for the tenants in a multi-tenant application. `IFeatureManager` is typically used by the *Feature Management Dialog*. However, you can inject it if you need to set a feature value.
`IFeatureManager` is the main service provided by this module. It reads and changes feature values for registered feature management providers. `IFeatureManager` is typically used by the *Feature Management Dialog*. However, you can inject it if you need to set a feature value directly.
> If you just want to read feature values, use the `IFeatureChecker` as explained in the [Features document](../framework/infrastructure/features.md).
@ -70,6 +158,8 @@ namespace Demo
}
````
`SetAsync` and the provider-specific extension methods validate the value against the feature definition's value validator. By default, setting a value equal to the fallback value clears the explicit provider value; pass `forceToSet: true` when an explicit value must be kept even if it currently matches the fallback. Use `DeleteAsync(providerName, providerKey)` to reset all values for a provider object to their fallbacks.
## Feature Management Providers
Features Management Module is extensible, just like the [features system](../framework/infrastructure/features.md). You can extend it by defining feature management providers. There are 4 pre-built feature management providers registered in the following order:
@ -86,7 +176,9 @@ If you want to create your own provider, implement the `IFeatureManagementProvid
````csharp
public class CustomFeatureProvider : FeatureManagementProvider
{
public override string Name => "Custom";
public const string ProviderName = "Custom";
public override string Name => ProviderName;
public CustomFeatureProvider(IFeatureManagementStore store)
: base(store)
@ -103,12 +195,77 @@ Once you create your provider class, you should register it using the `FeatureMa
The order of the providers are important. Providers are executed in the reverse order. That means the `CustomFeatureProvider` is executed first for this example. You can insert your provider in any order in the `Providers` list.
The `ProviderPolicies` entry is required when the custom provider is managed through `IFeatureAppService` or one of the reusable dialogs. Map the provider name to an authorization policy that grants access to the corresponding provider object. The application service rejects get, update and reset operations when no policy is mapped.
The management application service exposes get, update and reset operations through `IFeatureAppService`. The HTTP API maps the same operations to `GET`, `PUT` and `DELETE` requests at `/api/feature-management/features`, using `providerName` and `providerKey` to identify the managed object.
## Custom Value Validators
Feature definitions can use custom `IValueValidator` implementations. When those definitions are persisted or returned by the management API, the module must be able to reconstruct the validator from its serialized name. Define a parameterless validator and register a matching factory during pre-configuration:
````csharp
[Serializable]
[ValueValidator("URL")]
public class UrlValueValidator : ValueValidatorBase
{
public override bool IsValid(object? value)
{
return Uri.TryCreate(value?.ToString(), UriKind.Absolute, out _);
}
}
````
````csharp
public override void PreConfigureServices(ServiceConfigurationContext context)
new ValueValidatorFactory<UrlValueValidator>("URL")
);
});
}
````
The factory name must match the name supplied by `ValueValidatorAttribute`. The module registers factories for the built-in `NULL`, `BOOLEAN`, `NUMERIC` and `STRING` validators.
## Database Providers
The Entity Framework Core and MongoDB packages persist the same three record types: feature groups, feature definitions and feature values.
### Common
#### Table / Collection Prefix and Schema
All tables and collections use the `Abp` prefix by default. Set the static `AbpFeatureManagementDbProperties.DbTablePrefix` property to change the prefix. `AbpFeatureManagementDbProperties.DbSchema` changes the schema for database providers that support schemas.
#### Connection String
The module uses `AbpFeatureManagement` as the connection string name. If this connection string is not configured, it falls back to the `Default` connection string. See the [connection strings](../framework/fundamentals/connection-strings.md) documentation for details.
### Entity Framework Core
The Entity Framework Core provider maps the following tables:
* **AbpFeatureGroups**
* **AbpFeatures**
* **AbpFeatureValues**
### MongoDB
The MongoDB provider maps the following collections: