From f4b3d4b80616e086b3b9e8436260373e29435811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Tue, 15 Jun 2021 14:25:32 +0300 Subject: [PATCH] Documented Feature Management Module --- docs/en/Modules/Feature-Management.md | 105 ++++++++++++++++++++- docs/en/Modules/Setting-Management.md | 33 ++++++- docs/en/images/features-module-opening.png | Bin 0 -> 25000 bytes 3 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 docs/en/images/features-module-opening.png diff --git a/docs/en/Modules/Feature-Management.md b/docs/en/Modules/Feature-Management.md index 968b742092..9bbf344a01 100644 --- a/docs/en/Modules/Feature-Management.md +++ b/docs/en/Modules/Feature-Management.md @@ -1,5 +1,106 @@ # Feature Management Module -> This module implements the `IFeatureStore` to store and manage feature values in a database. See the [Features System document](../Features.md) to understand the features first. +The Feature Management module implements the `IFeatureManagementStore` interface defined by the [Feature System](../Features.md). + +> This document covers only the feature management module which persists feature values to a database. See [the features](../Features.md) document for more about the feature system. + +## How to Install + +This module comes as pre-installed (as NuGet/NPM packages) when you [create a new solution](https://abp.io/get-started) with the ABP Framework. You can continue to use it as package and get updates easily, or you can include its source code into your solution (see `get-source` [CLI](../CLI.md) command) to develop your custom module. + +### The Source Code + +The source code of this module can be accessed [here](https://github.com/abpframework/abp/tree/dev/modules/feature-management). The source code is licensed with [MIT](https://choosealicense.com/licenses/mit/), so you can freely use and customize it. + +## User Interface + +### Feature Management Dialog + +Feature management module provides a reusable dialog to manage features related to an object. For example, the [Tenant Management Module](Tenant-Management.md) uses it to manage permissions of tenants in the Tenant Management page. + +![features-module-opening](../images/features-module-opening.png) + +When you click *Actions* -> *Features* for a tenant, the feature management dialog is opened. An example screenshot from this dialog with two features defined: + +![features-modal](../images/features-modal.png) + +In this dialog, you can enable, disable or set values for the features for a tenant. + +## 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. + +> If you just want to read feature values, use the `IFeatureChecker` as explained in the [Features document](../Features.md). + +**Example: Get/set a feature's value for a tenant** + +````csharp +using System; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.FeatureManagement; + +namespace Demo +{ + public class MyService : ITransientDependency + { + private readonly IFeatureManager _featureManager; + + public MyService(IFeatureManager featureManager) + { + _featureManager = featureManager; + } + + public async Task SetFeatureDemoAsync(Guid tenantId, string value) + { + await _featureManager + .SetForTenantAsync(tenantId, "Feature1", value); + + var currentValue = await _featureManager + .GetOrNullForTenantAsync("Feature1", tenantId); + } + } +} +```` + +## Feature Management Providers + +Features Management Module is extensible, just like the [features system](../Features.md). You can extend it by defining feature management providers. There are 3 pre-built feature management providers registered it the following order: + +* `DefaultValueFeatureManagementProvider`: Gets the value from the default value of the feature definition. It can not set the default value since default values are hard-coded on the feature definition. +* `EditionFeatureManagementProvider`: Gets or sets the feature values for an edition. Edition is a group of features assigned to tenants. Edition system has not implemented by the Tenant Management module. You can implement it yourself or purchase the ABP Commercial [SaaS Module](https://commercial.abp.io/modules/Volo.Saas) which implements it and also provides more SaaS features, like subscription and payment. +* `TenantFeatureManagementProvider`: Gets or sets the features values for tenants. + +`IFeatureManager` uses these providers on get/set methods. Typically, every feature management provider defines extension methods on the `IFeatureManager` service (like `SetForTenantAsync` defined by the tenant feature management provider). + +If you want to create your own provider, implement the `IFeatureManagementProvider` interface or inherit from the `FeatureManagementProvider` base class: + +````csharp +public class CustomFeatureProvider : FeatureManagementProvider +{ + public override string Name => "Custom"; + + public CustomFeatureProvider(IFeatureManagementStore store) + : base(store) + { + } +} +```` + +`FeatureManagementProvider` base class makes the default implementation (using the `IFeatureManagementStore`) for you. You can override base methods as you need. Every provider must have a unique name, which is `Custom` in this example (keep it short since it is saved to database for each feature value record). + +Once you create your provider class, you should register it using the `FeatureManagementOptions` [options class](../Options.md): + +````csharp +Configure(options => +{ + options.Providers.Add(); +}); +```` + +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. + +## See Also + +* [Features](../Features.md) -TODO \ No newline at end of file diff --git a/docs/en/Modules/Setting-Management.md b/docs/en/Modules/Setting-Management.md index dff8da3f8e..9104daf8a6 100644 --- a/docs/en/Modules/Setting-Management.md +++ b/docs/en/Modules/Setting-Management.md @@ -83,4 +83,35 @@ Setting Management module is extensible, just like the [setting system](../Setti * `TenantSettingManagementProvider`: Gets or sets the setting value for a tenant. * `UserSettingManagementProvider`: Gets 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). \ No newline at end of file +`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). + +If you want to create your own provider, implement the `ISettingManagementProvider` interface or inherit from the `SettingManagementProvider` base class: + +````csharp +public class CustomSettingProvider : SettingManagementProvider +{ + public override string Name => "Custom"; + + public CustomSettingProvider(ISettingManagementStore store) + : base(store) + { + } +} +```` + +`SettingManagementProvider` base class makes the default implementation (using the `ISettingManagementStore`) for you. You can override base methods as you need. Every provider must have a unique name, which is `Custom` in this example (keep it short since it is saved to database for each feature value record). + +Once you create your provider class, you should register it using the `SettingManagementOptions` [options class](../Options.md): + +````csharp +Configure(options => +{ + options.Providers.Add(); +}); +```` + +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. + +## See Also + +* [Settings](../Settings.md) \ No newline at end of file diff --git a/docs/en/images/features-module-opening.png b/docs/en/images/features-module-opening.png new file mode 100644 index 0000000000000000000000000000000000000000..bd99604cd7fb0b34b48de1299bdd8920fbf9cb4f GIT binary patch literal 25000 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