Merge pull request #8567 from abpframework/auto-merge/rel-4-3/288

Merge branch dev with rel-4.3
pull/8371/head^2
liangshiwei 5 years ago committed by GitHub
commit 12c6405b9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,71 @@
# Cancellation Token Provider
A `CancellationToken` enables cooperative cancellation between threads, thread pool work items, or `Task` objects. To handle the possible cancellation of the operation, ABP Framework provides `ICancellationTokenProvider` to obtain the `CancellationToken` itself from the source.
> To get more information about `CancellationToken`, see [Microsoft Documentation](https://docs.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken).
## ICancellationTokenProvider
`ICancellationTokenProvider` is an abstraction to provide `CancellationToken` for different scenarios.
Generally, you should pass the `CancellationToken` as a parameter for your method to use it. With the `ICancellationTokenProvider` you don't need to pass `CancellationToken` for every method. `ICancellationTokenProvider` can be injected with the **dependency injection** and provides the token from it's source.
**Example:**
```csharp
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Threading;
namespace MyProject
{
public class MyService : ITransientDependency
{
private readonly ICancellationTokenProvider _cancellationTokenProvider;
public MyService(ICancellationTokenProvider cancellationTokenProvider)
{
_cancellationTokenProvider = cancellationTokenProvider;
}
public async Task DoItAsync()
{
while (_cancellationTokenProvider.Token.IsCancellationRequested == false)
{
// ...
}
}
}
}
```
## Built-in providers
- `NullCancellationTokenProvider`
The `NullCancellationTokenProvider` is a built in provider and it supply always `CancellationToken.None`.
- `HttpContextCancellationTokenProvider`
The `HttpContextCancellationTokenProvider` is a built in default provider for ABP Web applications. It simply provides a `CancellationToken` that is source of the web request from the `HttpContext`.
## Implementing the ICancellationTokenProvider
You can easily create your CancellationTokenProvider by creating a class that implements the `ICancellationTokenProvider` interface, as shown below:
```csharp
using System.Threading;
namespace AbpDemo
{
public class MyCancellationTokenProvider : ICancellationTokenProvider
{
public CancellationToken Token { get; }
private MyCancellationTokenProvider()
{
}
}
}
```

@ -1,3 +1,117 @@
# 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
> 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
```
## 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 PaymentFeature : GlobalFeature
{
public const string Name = "Shopping.Payment";
public PaymentFeature(GlobalModuleFeatures module) : base(module)
{
}
}
```
### Define Global Module Features
All features of a module have to be defined in a Global Module Features class.
```csharp
public class GlobalShoppingFeatures : GlobalModuleFeatures
{
public const string ModuleName = "Shopping";
public GlobalShoppingFeatures(GlobalFeatureManager featureManager) : base(featureManager)
{
AddFeature(new PaymentFeature(this));
// And more features...
}
}
```
## Usage
### Enable/Disable Features
Global features are managed by modules. Module Features have to be added to Modules of GlobalFeatureManager.
```csharp
// 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<PaymentFeature>();
shoppingGlobalFeatures.Disable<PaymentFeature>();
// 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<PaymentFeature>()
GlobalFeatureManager.Instance.IsEnabled("Shopping.Payment")
```
Both methods return `bool`.
```csharp
if (GlobalFeatureManager.Instance.IsEnabled<PaymentFeature>())
{
// Some strong payment codes here...
}
```
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 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** to make sure it runs one time.
```csharp
private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();
public override void PreConfigureServices(ServiceConfigurationContext context)
{
OneTimeRunner.Run(() =>
{
GlobalFeatureManager.Instance.Modules.Foo().EnableAll();
});
}
```
## 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.

@ -343,6 +343,10 @@
{
"text": "Virtual File System",
"path": "Virtual-File-System.md"
},
{
"text": "Cancellation Token Provider",
"path": "Cancellation-Token-Provider.md"
}
]
},

@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
namespace Volo.Abp.GlobalFeatures
{

@ -1,5 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using JetBrains.Annotations;
namespace Volo.Abp.GlobalFeatures
@ -26,7 +26,6 @@ namespace Volo.Abp.GlobalFeatures
}
public virtual bool IsEnabled<TFeature>()
where TFeature : GlobalFeature
{
return IsEnabled(GlobalFeatureNameAttribute.GetName<TFeature>());
}

@ -1,4 +1,4 @@
using System;
using System;
using System.Linq;
using System.Reflection;
using JetBrains.Annotations;
@ -17,7 +17,6 @@ namespace Volo.Abp.GlobalFeatures
}
public static string GetName<TFeature>()
where TFeature : GlobalFeature
{
return GetName(typeof(TFeature));
}

@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Collections.Immutable;
using JetBrains.Annotations;

@ -21,11 +21,7 @@ namespace Volo.Abp.Ldap
context.Services.AddAbpDynamicOptions<AbpLdapOptions, AbpAbpLdapOptionsManager>();
var configuration = context.Services.GetConfiguration();
var ldapConfiguration = configuration["Ldap"];
if (!ldapConfiguration.IsNullOrEmpty())
{
Configure<AbpLdapOptions>(configuration.GetSection("Ldap"));
}
Configure<AbpLdapOptions>(configuration.GetSection("Ldap"));
Configure<AbpVirtualFileSystemOptions>(options =>
{

Loading…
Cancel
Save