mirror of https://github.com/abpframework/abp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
146 lines
4.8 KiB
146 lines
4.8 KiB
# Global Features
|
|
Global Feature system is used to enable/disable an application feature on development time. It is done on the development time, because some **services** (e.g. controllers) are removed from the application model and **database tables** are not created for the disabled features, which is not possible on runtime.
|
|
|
|
Global Features system is especially useful if you want to develop a reusable application module with optional features. If the final application doesn't want to use some of the features, it can disable these features.
|
|
|
|
> If you are looking for a system to enable/disable features based on current tenant or any other condition, please see the [Features](Features.md) document.
|
|
|
|
## Installation
|
|
> This package is already installed by default with the startup template. So, most of the time, you don't need to install it manually.
|
|
|
|
### Using the ABP CLI
|
|
|
|
Open a command line window in the folder of the project (.csproj file) and type the following command:
|
|
|
|
```bash
|
|
abp add-package Volo.Abp.GlobalFeatures
|
|
```
|
|
|
|
## Defining a Global Feature
|
|
|
|
A feature class is something like that:
|
|
|
|
```csharp
|
|
[GlobalFeatureName("Shopping.Payment")]
|
|
public class PaymentFeature
|
|
{
|
|
|
|
}
|
|
```
|
|
|
|
## Enable/Disable Global Features
|
|
|
|
Use `GlobalFeatureManager.Instance` to enable/disable a global feature.
|
|
|
|
```csharp
|
|
// Able to Enable/Disable with generic type parameter.
|
|
GlobalFeatureManager.Instance.Enable<PaymentFeature>();
|
|
GlobalFeatureManager.Instance.Disable<PaymentFeature>();
|
|
|
|
// Also able to Enable/Disable with string feature name.
|
|
GlobalFeatureManager.Instance.Enable("Shopping.Payment");
|
|
GlobalFeatureManager.Instance.Disable("Shopping.Payment");
|
|
```
|
|
|
|
> Global Features are disabled unless they are explicitly enabled.
|
|
|
|
### Where to Configure Global Features?
|
|
|
|
Global Features have to be configured before application startup. Since the `GlobalFeatureManager.Instance` is a singleton object, one-time, static configuration is enough. It is suggested to enable/disable global features in `PreConfigureServices` method of your module. You can use the `OneTimeRunner` utility class to make sure it runs only once:
|
|
|
|
```csharp
|
|
private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();
|
|
public override void PreConfigureServices(ServiceConfigurationContext context)
|
|
{
|
|
OneTimeRunner.Run(() =>
|
|
{
|
|
GlobalFeatureManager.Instance.Enable<PaymentFeature>();
|
|
});
|
|
}
|
|
```
|
|
|
|
## Check for a Global Feature
|
|
|
|
```csharp
|
|
GlobalFeatureManager.Instance.IsEnabled<PaymentFeature>()
|
|
GlobalFeatureManager.Instance.IsEnabled("Shopping.Payment")
|
|
```
|
|
|
|
Both methods return `bool`. So, you can write conditional logic as shown below:
|
|
|
|
```csharp
|
|
if (GlobalFeatureManager.Instance.IsEnabled<PaymentFeature>())
|
|
{
|
|
// Some strong payment codes here...
|
|
}
|
|
```
|
|
|
|
### RequiresGlobalFeature Attribute
|
|
|
|
Beside the manual check, there is `[RequiresGlobalFeature]` attribute to check it declaratively for a controller or page. ABP returns HTTP Response `404` if the related feature was disabled.
|
|
|
|
```csharp
|
|
[RequiresGlobalFeature(typeof(PaymentFeature))]
|
|
public class PaymentController : AbpController
|
|
{
|
|
|
|
}
|
|
```
|
|
|
|
## Grouping Features of a Module
|
|
|
|
It is common to group global features of a module to allow the final application developer easily discover and configure the features. Following example shows how to group features of a module.
|
|
|
|
Assume that we've defined a global feature for `Subscription` feature of an `Ecommerce` module:
|
|
|
|
```csharp
|
|
[GlobalFeatureName("Ecommerce.Subscription")]
|
|
public class SubscriptionFeature : GlobalFeature
|
|
{
|
|
public SubscriptionFeature(GlobalModuleFeatures module)
|
|
: base(module)
|
|
{
|
|
}
|
|
}
|
|
```
|
|
|
|
You can define as many features as you need in your module. Then define a class to group these features together:
|
|
|
|
```csharp
|
|
public class GlobalEcommerceFeatures : GlobalModuleFeatures
|
|
{
|
|
public const string ModuleName = "Ecommerce";
|
|
|
|
public SubscriptionFeature Subscription => GetFeature<SubscriptionFeature>();
|
|
|
|
public GlobalEcommerceFeatures(GlobalFeatureManager featureManager)
|
|
: base(featureManager)
|
|
{
|
|
AddFeature(new SubscriptionFeature(this));
|
|
}
|
|
}
|
|
```
|
|
|
|
Finally, you can create an extension method on `GlobalModuleFeaturesDictionary`:
|
|
|
|
```csharp
|
|
public static class GlobalModuleFeaturesDictionaryEcommerceExtensions
|
|
{
|
|
public static GlobalEcommerceFeatures Ecommerce(
|
|
this GlobalModuleFeaturesDictionary modules)
|
|
{
|
|
return modules.GetOrAdd(
|
|
GlobalEcommerceFeatures.ModuleName,
|
|
_ => new GlobalEcommerceFeatures(modules.FeatureManager)
|
|
) as GlobalEcommerceFeatures;
|
|
}
|
|
```
|
|
|
|
Then `GlobalFeatureManager.Instance.Modules.Ecommerce()` can be used to access the global features of your module. Examples usages:
|
|
|
|
```csharp
|
|
GlobalFeatureManager.Instance.Modules.Ecommerce().Subscription.Enable();
|
|
GlobalFeatureManager.Instance.Modules.Ecommerce().EnableAll();
|
|
```
|
|
|