From 8a57d6344b5f2e668393f3d9a126ec2711533fa4 Mon Sep 17 00:00:00 2001 From: enisn Date: Wed, 7 Apr 2021 18:21:49 +0300 Subject: [PATCH 1/5] 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 From 13ec840a2bd52b66329a82490238fd4a6c798a1e Mon Sep 17 00:00:00 2001 From: enisn Date: Thu, 8 Apr 2021 11:46:52 +0300 Subject: [PATCH 2/5] Docs - Add missing header to Global Features document --- docs/en/Global-Features.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Global-Features.md b/docs/en/Global-Features.md index f9504a06b8..135a2a3fdd 100644 --- a/docs/en/Global-Features.md +++ b/docs/en/Global-Features.md @@ -1,7 +1,7 @@ +# 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. ## Installation - Global Feature system is pre-installed in abp startup templates. No need any installation manually. ## Usage From ef232f5d00063104f291a71c5281ae2d3bd09c29 Mon Sep 17 00:00:00 2001 From: enisn Date: Thu, 8 Apr 2021 11:50:02 +0300 Subject: [PATCH 3/5] Docs - Formatting for Global-Featured.md --- docs/en/Global-Features.md | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/docs/en/Global-Features.md b/docs/en/Global-Features.md index 135a2a3fdd..0768c2f9dc 100644 --- a/docs/en/Global-Features.md +++ b/docs/en/Global-Features.md @@ -20,8 +20,6 @@ GlobalFeatureManager.Instance.Modules.CmsKit().Enable(CommentsFeature.Name); //A GlobalFeatureManager.Instance.Modules.CmsKit().Enable("CmsKit.Comments"); //Alternative: Use magic string ``` - - ### Check if a feature is enabled ```csharp @@ -41,14 +39,10 @@ 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 @@ -65,7 +59,6 @@ public class FooBarFeature : GlobalFeature ``` ### Define Global Module Features - All global features of a module should be provided by a single **GlobalModuleFeatures** class. ```csharp @@ -82,10 +75,7 @@ public class GlobalFooFeatures : GlobalModuleFeatures } ``` - - ### Define Global Module Features Dictionary Extensions - An extension method is better to configure global fetures easily. ```csharp @@ -114,10 +104,7 @@ 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 @@ -131,8 +118,5 @@ public override void PreConfigureServices(ServiceConfigurationContext context) } ``` - - ## See also - - [Differences Between Features & Global Features](Differences-between-features-and-global-features.md) \ No newline at end of file From a7bb0bdf7609d7c630fdff2c9338f06ff429fd26 Mon Sep 17 00:00:00 2001 From: enisn Date: Thu, 8 Apr 2021 18:04:39 +0300 Subject: [PATCH 4/5] Docs - Update Global Features documentation --- ...es-between-features-and-global-features.md | 9 -- docs/en/Global-Features.md | 129 +++++++++--------- 2 files changed, 64 insertions(+), 74 deletions(-) delete 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 deleted file mode 100644 index 7058696341..0000000000 --- a/docs/en/Differences-between-features-and-global-features.md +++ /dev/null @@ -1,9 +0,0 @@ -# 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 0768c2f9dc..d75681dbb3 100644 --- a/docs/en/Global-Features.md +++ b/docs/en/Global-Features.md @@ -2,110 +2,107 @@ 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. ## Installation -Global Feature system is pre-installed in abp startup templates. No need any installation manually. +> This package is already installed by default with the startup template. So, most of the time, you don't need to install it manually. -## Usage +### Using the ABP CLI -### Enable/Disable Existing Features +Open a command line window in the folder of the project (.csproj file) and type the following command: -```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 +```bash +abp add-package Volo.Abp.GlobalFeatures ``` -### 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 class PaymentFeature : GlobalFeature { - public const string Name = "Foo.Bar"; - internal FooBarFeature( - [NotNull] GlobalFooFeatures features - ) : base(features) + public const string Name = "Shopping.Payment"; + + public PaymentFeature(GlobalModuleFeatures module) : base(module) { } } ``` ### Define Global Module Features -All global features of a module should be provided by a single **GlobalModuleFeatures** class. + +All features of a module have to be defined in a Global Module Features class. ```csharp -public class GlobalFooFeatures : GlobalModuleFeatures +public class GlobalShoppingFeatures : GlobalModuleFeatures { - public const string ModuleName = "Foo"; - - public FooBarFeature FooBar => GetFeature(); - - public GlobalFooFeatures([NotNull] GlobalFeatureManager featureManager) - : base(featureManager) + public const string ModuleName = "Shopping"; + + public GlobalShoppingFeatures(GlobalFeatureManager featureManager) : base(featureManager) { + AddFeature(new PaymentFeature(this)); + // And more features... } } ``` -### Define Global Module Features Dictionary Extensions -An extension method is better to configure global fetures easily. + + +## Usage + +### Enable/Disable Features + +Global features are managed by modules. Module Features have to be added to Modules of GlobalFeatureManager. ```csharp -public static class GlobalModuleFeaturesDictionaryFooExtensions +// GerOrAdd might be useful to be sure module features are added. +var shoppingGlobalFeatures = GlobalFeatureManager.Instance.Modules + .GetOrAdd( + GlobalShoppingFeatures.ModuleName, + ()=> new GlobalShoppingFeatures(GlobalFeatureManager.Instance)); + +// Able to Enable/Disable with generic type parameter. +shoppingGlobalFeatures.Enable(); +shoppingGlobalFeatures.Disable(); + +// Also able to Enable/Disable with string feature name. +shoppingGlobalFeatures.Enable(PaymentFeature.Name); +shoppingGlobalFeatures.Disable("Shopping.Payment"); +``` + +### Check if a feature is enabled + +```csharp +GlobalFeatureManager.Instance.IsEnabled() +GlobalFeatureManager.Instance.IsEnabled("Shopping.Payment") +``` + +Both methods return `bool`. + +```csharp +if (GlobalFeatureManager.Instance.IsEnabled()) { - public static GlobalFooFeatures Foo( - [NotNull] this GlobalModuleFeaturesDictionary modules) - { - Check.NotNull(modules, nameof(modules)); - return modules - .GetOrAdd( - GlobalFooFeatures.ModuleName, - _ => new GlobalFooFeatures(modules.FeatureManager) - ) - as GlobalFooFeatures; - } + // Some strong payment codes here... } ``` -Accessing module & module features look like: +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 -GlobalFeatureManager.Instance.Modules.Foo(); -GlobalFeatureManager.Instance.Modules.Foo().FooBar; -GlobalFeatureManager.Instance.Modules.Foo().FooBar.Enable(); -GlobalFeatureManager.Instance.Modules.Foo().Enable(); +[RequiresGlobalFeature(typeof(CommentsFeature))] +public class PaymentController : AbpController +{ + // ... +} ``` ## When to configure Global Features? -Global Features have to be configured before application startup. So best place to configuring it is `PreConfigureServices` with **OneTimeRunner**. +Global Features have to be configured before application startup. So best place to configuring it is `PreConfigureServices` with **OneTimeRunner** to make sure it runs one time. ```csharp private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner(); @@ -118,5 +115,7 @@ public override void PreConfigureServices(ServiceConfigurationContext context) } ``` -## See also -- [Differences Between Features & Global Features](Differences-between-features-and-global-features.md) \ No newline at end of file +## Features vs Global Features +[Features](Features.md) & [Global Features](Global-Features.md) are totally different systems. + +Features are used to switch on/off application feature for each tenant. So Features, only hides disabled ones, but with Global Features, disabled features pretends like never existed in application. \ No newline at end of file From ac1974fc7cca8e31ef958c06907bb7dd01385891 Mon Sep 17 00:00:00 2001 From: enisn Date: Thu, 8 Apr 2021 18:05:54 +0300 Subject: [PATCH 5/5] Docs - Formatting Global-Features.md --- docs/en/Global-Features.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/en/Global-Features.md b/docs/en/Global-Features.md index d75681dbb3..cfbf3f98b7 100644 --- a/docs/en/Global-Features.md +++ b/docs/en/Global-Features.md @@ -12,8 +12,6 @@ Open a command line window in the folder of the project (.csproj file) and type abp add-package Volo.Abp.GlobalFeatures ``` - - ## Implementation Global Feature system aims module based feature management . A module has to have own Global Features itself. @@ -51,8 +49,6 @@ public class GlobalShoppingFeatures : GlobalModuleFeatures } ``` - - ## Usage ### Enable/Disable Features