项目

全局功能

全局功能系统用于在开发阶段启用或禁用应用程序功能。此操作必须在开发时完成,因为某些服务(例如控制器)会从应用程序模型中移除,并且禁用功能对应的数据库表不会被创建,这些操作在运行时无法实现。

全局功能系统对于开发具有可选功能的可复用应用程序模块尤为有用。如果最终应用程序不希望使用某些功能,可以禁用这些功能。

如需根据当前租户或其他条件启用/禁用功能的系统,请参阅功能文档。

安装

此包已默认随启动模板安装。因此,大多数情况下无需手动安装。

在项目文件夹(.csproj文件所在目录)中打开命令行窗口,输入以下命令:

abp add-package Volo.Abp.GlobalFeatures

定义全局功能

功能类定义示例如下:

[GlobalFeatureName("Shopping.Payment")]
public class PaymentFeature
{
    
}

启用/禁用全局功能

使用GlobalFeatureManager.Instance来启用或禁用全局功能。

// 可通过泛型类型参数启用/禁用
GlobalFeatureManager.Instance.Enable<PaymentFeature>();
GlobalFeatureManager.Instance.Disable<PaymentFeature>();

// 也可通过字符串功能名称启用/禁用
GlobalFeatureManager.Instance.Enable("Shopping.Payment");
GlobalFeatureManager.Instance.Disable("Shopping.Payment");

全局功能默认处于禁用状态,除非显式启用。

在何处配置全局功能?

全局功能必须在应用程序启动前配置。由于GlobalFeatureManager.Instance是单例对象,只需进行一次静态配置。建议在模块的PreConfigureServices方法中启用/禁用全局功能。可使用OneTimeRunner工具类确保仅执行一次:

private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();
public override void PreConfigureServices(ServiceConfigurationContext context)
{
  OneTimeRunner.Run(() =>
  {
   GlobalFeatureManager.Instance.Enable<PaymentFeature>();
  });
}

检查全局功能状态

GlobalFeatureManager.Instance.IsEnabled<PaymentFeature>()
GlobalFeatureManager.Instance.IsEnabled("Shopping.Payment")

两种方法均返回bool值,因此可编写条件逻辑如下:

if (GlobalFeatureManager.Instance.IsEnabled<PaymentFeature>())
{
    // 此处放置支付相关代码...
}

RequiresGlobalFeature特性

除手动检查外,还可使用[RequiresGlobalFeature]特性对控制器或页面进行声明式检查。如果相关功能被禁用,ABP将返回HTTP响应404

[RequiresGlobalFeature(typeof(PaymentFeature))]
public class PaymentController : AbpController
{

}

模块功能分组

通常会对模块的全局功能进行分组,以便最终应用程序开发者轻松发现和配置功能。以下示例展示如何对模块功能进行分组。

假设我们为Ecommerce模块的Subscription功能定义了全局功能:

[GlobalFeatureName("Ecommerce.Subscription")]
public class SubscriptionFeature : GlobalFeature
{
    public SubscriptionFeature(GlobalModuleFeatures module)
        : base(module)
    {
    }
}

可在模块中定义任意数量的功能,然后通过以下类将这些功能分组:

public class GlobalEcommerceFeatures : GlobalModuleFeatures
{
    public const string ModuleName = "Ecommerce";

    public SubscriptionFeature Subscription => GetFeature<SubscriptionFeature>();
 
    public GlobalEcommerceFeatures(GlobalFeatureManager featureManager)
        : base(featureManager)
    {
        AddFeature(new SubscriptionFeature(this));
    }
}

最后,可在GlobalModuleFeaturesDictionary上创建扩展方法:

public static class GlobalModuleFeaturesDictionaryEcommerceExtensions
{
    public static GlobalEcommerceFeatures Ecommerce(
        this GlobalModuleFeaturesDictionary modules)
    {
        return modules.GetOrAdd(
            GlobalEcommerceFeatures.ModuleName,
            _ => new GlobalEcommerceFeatures(modules.FeatureManager)
        ) as GlobalEcommerceFeatures;
  }

随后可通过GlobalFeatureManager.Instance.Modules.Ecommerce()访问模块的全局功能。使用示例如下:

GlobalFeatureManager.Instance.Modules.Ecommerce().Subscription.Enable();
GlobalFeatureManager.Instance.Modules.Ecommerce().EnableAll();
在本文档中