mirror of https://github.com/abpframework/abp.git
2 changed files with 146 additions and 2 deletions
@ -0,0 +1,9 @@ |
|||||
|
# Differences between Features & Global Features |
||||
|
|
||||
|
[Features](Features.md) & [Global Features](Global-Features.md) are totally different systems. |
||||
|
|
||||
|
- Features can be switched at runtime but global features can't be. |
||||
|
- Features can be managed by users & system administrators while application running but Global Features system is for Developers and can be managed at development time. |
||||
|
- Features can be used as Feature-Flag but Global Features can't. |
||||
|
- Features loads all disabled features to application and just hide them but Global Features system doesn't load disabled features and even prevents table creating in database. |
||||
|
|
||||
@ -1,3 +1,138 @@ |
|||||
# Global Features |
The purpose of the Global Feature System is to **add a module to your application but disable the features you don't want to use** (or enable only the ones you need). Notice that the features are not determined on runtime, you must select the features **on development time**. Because it will not create database tables, APIs and other stuff for unused features, which is not possible to change then on the runtime. |
||||
|
|
||||
TODO (see [#5061](https://github.com/abpframework/abp/issues/5061) until this is documented). |
## Installation |
||||
|
|
||||
|
Global Feature system is pre-installed in abp startup templates. No need any installation manually. |
||||
|
|
||||
|
## Usage |
||||
|
|
||||
|
### Enable/Disable Existing Features |
||||
|
|
||||
|
```csharp |
||||
|
//Enable all the CMS Kit Features |
||||
|
GlobalFeatureManager.Instance.Modules.CmsKit().EnableAll(); |
||||
|
//Disable all the CMS Kit Features (while it is already disabled by default) |
||||
|
GlobalFeatureManager.Instance.Modules.CmsKit().DisableAll(); |
||||
|
//Enable a feature |
||||
|
GlobalFeatureManager.Instance.Modules.CmsKit().Comments.Enable(); |
||||
|
GlobalFeatureManager.Instance.Modules.CmsKit().Enable<CommentsFeature>(); //Alternative: use the feature class |
||||
|
GlobalFeatureManager.Instance.Modules.CmsKit().Enable(CommentsFeature.Name); //Alternative: use the feature name |
||||
|
GlobalFeatureManager.Instance.Modules.CmsKit().Enable("CmsKit.Comments"); //Alternative: Use magic string |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
|
||||
|
### Check if a feature is enabled |
||||
|
|
||||
|
```csharp |
||||
|
GlobalFeatureManager.Instance.IsEnabled<CommentsFeature>(); |
||||
|
GlobalFeatureManager.Instance.IsEnabled(CommentsFeature.Name); //Alternative |
||||
|
``` |
||||
|
|
||||
|
Both methods return `bool`. |
||||
|
|
||||
|
Beside the manual check, there is `[RequiresGlobalFeature]` attribute to check it declaratively for a controller or page. ABP returns 404 if the related feature was disabled. |
||||
|
|
||||
|
```csharp |
||||
|
[RequiresGlobalFeature(typeof(CommentsFeature))] |
||||
|
public class CommentController : AbpController |
||||
|
{ |
||||
|
// ... |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
|
||||
|
## Implementation |
||||
|
|
||||
|
Global Feature system aims module based feature management . A module has to have own Global Features itself. |
||||
|
|
||||
|
### Define a Global Feature |
||||
|
|
||||
|
A feature class is something like that: |
||||
|
|
||||
|
```csharp |
||||
|
[GlobalFeatureName(Name)] |
||||
|
public class FooBarFeature : GlobalFeature |
||||
|
{ |
||||
|
public const string Name = "Foo.Bar"; |
||||
|
internal FooBarFeature( |
||||
|
[NotNull] GlobalFooFeatures features |
||||
|
) : base(features) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
### Define Global Module Features |
||||
|
|
||||
|
All global features of a module should be provided by a single **GlobalModuleFeatures** class. |
||||
|
|
||||
|
```csharp |
||||
|
public class GlobalFooFeatures : GlobalModuleFeatures |
||||
|
{ |
||||
|
public const string ModuleName = "Foo"; |
||||
|
|
||||
|
public FooBarFeature FooBar => GetFeature<FooBarFeature>(); |
||||
|
|
||||
|
public GlobalFooFeatures([NotNull] GlobalFeatureManager featureManager) |
||||
|
: base(featureManager) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
|
||||
|
### Define Global Module Features Dictionary Extensions |
||||
|
|
||||
|
An extension method is better to configure global fetures easily. |
||||
|
|
||||
|
```csharp |
||||
|
public static class GlobalModuleFeaturesDictionaryFooExtensions |
||||
|
{ |
||||
|
public static GlobalFooFeatures Foo( |
||||
|
[NotNull] this GlobalModuleFeaturesDictionary modules) |
||||
|
{ |
||||
|
Check.NotNull(modules, nameof(modules)); |
||||
|
return modules |
||||
|
.GetOrAdd( |
||||
|
GlobalFooFeatures.ModuleName, |
||||
|
_ => new GlobalFooFeatures(modules.FeatureManager) |
||||
|
) |
||||
|
as GlobalFooFeatures; |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
Accessing module & module features look like: |
||||
|
|
||||
|
```csharp |
||||
|
GlobalFeatureManager.Instance.Modules.Foo(); |
||||
|
GlobalFeatureManager.Instance.Modules.Foo().FooBar; |
||||
|
GlobalFeatureManager.Instance.Modules.Foo().FooBar.Enable(); |
||||
|
GlobalFeatureManager.Instance.Modules.Foo().Enable<FooBarFeature>(); |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
|
||||
|
## When to configure Global Features? |
||||
|
|
||||
|
Global Features have to be configured before application startup. So best place to configuring it is `PreConfigureServices` with **OneTimeRunner**. |
||||
|
|
||||
|
```csharp |
||||
|
private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner(); |
||||
|
public override void PreConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
OneTimeRunner.Run(() => |
||||
|
{ |
||||
|
GlobalFeatureManager.Instance.Modules.Foo().EnableAll(); |
||||
|
}); |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
|
||||
|
## See also |
||||
|
|
||||
|
- [Differences Between Features & Global Features](Differences-between-features-and-global-features.md) |
||||
Loading…
Reference in new issue