From 8a57d6344b5f2e668393f3d9a126ec2711533fa4 Mon Sep 17 00:00:00 2001 From: enisn Date: Wed, 7 Apr 2021 18:21:49 +0300 Subject: [PATCH] Docs - Add Global Features docs --- ...es-between-features-and-global-features.md | 9 ++ docs/en/Global-Features.md | 139 +++++++++++++++++- 2 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 docs/en/Differences-between-features-and-global-features.md diff --git a/docs/en/Differences-between-features-and-global-features.md b/docs/en/Differences-between-features-and-global-features.md new file mode 100644 index 0000000000..7058696341 --- /dev/null +++ b/docs/en/Differences-between-features-and-global-features.md @@ -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. + diff --git a/docs/en/Global-Features.md b/docs/en/Global-Features.md index a0a593288c..f9504a06b8 100644 --- a/docs/en/Global-Features.md +++ b/docs/en/Global-Features.md @@ -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). \ No newline at end of file +## 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(); //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(); +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(); + + 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(); +``` + + + +## 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) \ No newline at end of file