mirror of https://github.com/abpframework/abp
parent
84630100c3
commit
8a57d6344b
@ -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