文章目录

  • 简介
  • 检查特征
    • RequiresFeature属性
    • 关于拦截
    • IFeatureChecker服务
      • IsEnabledAsync
      • GetOrNullAsync
      • 扩展方法
  • 定义特征
    • FeatureDefinitionProvider
    • 其他特征属性
    • 特征管理模式
    • 子特征
    • 更改从属模块的特征定义
  • 在客户端检查特征
    • ASP.NET Core MVC / Razor页面用户界面
    • Angular UI
  • 特征管理
  • 高级主题
    • 特征值提供程序
    • 特征仓库

简介

ABP特征系统用于在运行时启用禁用更改应用程序特征的行为

特征的运行时值通常是一个boolean值,例如true(启用)或false(禁用)。但是,您可以获取/设置任何类型的特征值。

特征系统最初旨在控制多租户应用程序中的租户特征。但是,它是可扩展的,并且能够在任何条件下确定特征。

特征系统是通过Volo.Abp.Features NuGet包实现的。大多数情况下,您不需要手动安装它,因为它已随应用程序启动模板一起预安装。

注意:此文基于版本3.1时的文档进行翻译的

检查特征

在解释定义特征之前,让我们看一下如何在应用程序代码中检查特征值。

RequiresFeature属性

[RequiresFeature]属性(在Volo.Abp.Features名称空间中定义)用于声明性地检查特征是否true(启用)。这是这些boolean特征的有用快捷方式。

示例:检查是否启用了“PDF报告”特征

public class ReportingAppService : ApplicationService, IReportingAppService
{[RequiresFeature("MyApp.PdfReporting")]public async Task<PdfReportResultDto> GetPdfReportAsync(){//TODO...}
}
  • RequiresFeature(...)只需获取特征名称即可检查它是否已启用。如果未启用,则将抛出授权异常,并将适当的响应返回给客户端。

  • [RequiresFeature]可以用于方法。当您将它用于一个类时,该类的所有方法都需要给定的特征。

  • RequiresFeature可能会获得多个特征名称,例如[RequiresFeature("Feature1", "Feature2")]。在这种情况下,ABP检查是否启用了任何特征。使用RequiresAll选项,例如[RequiresFeature("Feature1", "Feature2", RequiresAll = true)]强制检查要启用的所有特征。

  • 方法或类支持多次使用[RequiresFeature]属性。在这种情况下,ABP check会检查所有它们。

特征名称可以是任意字符串。对于某个特征,它应该是唯一的。

关于拦截

ABP框架使用拦截系统使[RequiresFeature]属性正常工作。因此,它可以与从依赖注入注入的任何类(应用程序服务,控制器…)一起使用。

但是,为了使它起作用,应该遵循一些规则

  • 如果您不是通过接口(如IMyService注入服务,则该服务的方法必须为virtual。否则,动态代理/拦截系统将无法工作。

  • 仅拦截async方法(返回一个TaskTask<T>的方法)。

控制器和razor页面方法有一个例外。它们不需要上述规则,因为在这种情况下,ABP Framework使用动作/页面过滤器来实现特征检查。

IFeatureChecker服务

IFeatureChecker允许检查您的应用程序代码中的特征。

IsEnabledAsync

如果启用给定特征则返回true。因此,您可以有条件地执行业务流程。

示例:检查是否启用了“PDF报告”特征

public class ReportingAppService : ApplicationService, IReportingAppService
{private readonly IFeatureChecker _featureChecker;public ReportingAppService(IFeatureChecker featureChecker){_featureChecker = featureChecker;}public async Task<PdfReportResultDto> GetPdfReportAsync(){if (await _featureChecker.IsEnabledAsync("MyApp.PdfReporting")){//TODO...}else{//TODO...   }}
}

IsEnabledAsync 通过重载在一个方法调用中检查多个特征。

GetOrNullAsync

获取特征的当前值。此方法返回string,因此你可以通过转换string来存储任何类型的值。

示例:检查允许的最大产品数量

public class ProductController : AbpController
{private readonly IFeatureChecker _featureChecker;public ProductController(IFeatureChecker featureChecker){_featureChecker = featureChecker;}public async Task<IActionResult> Create(CreateProductModel model){var currentProductCount = await GetCurrentProductCountFromDatabase();//GET THE FEATURE VALUEvar maxProductCountLimit =await _featureChecker.GetOrNullAsync("MyApp.MaxProductCount");if (currentProductCount >= Convert.ToInt32(maxProductCountLimit)){throw new BusinessException("MyApp:ReachToMaxProductCountLimit",$"You can not create more than {maxProductCountLimit} products!");}//TODO: Create the product in the database...}private async Task<int> GetCurrentProductCountFromDatabase(){throw new System.NotImplementedException();}
}

本示例使用数字值作为SaaS应用程序中用户/租户的特征限制产品计数。

您可以使用GetAsync方法的一般重载,而不是将值手动转换为int

var maxProductCountLimit = await _featureChecker.GetAsync<int>("MyApp.MaxProductCount");

扩展方法

IFeatureChecker接口有一些有用的扩展方法。

  • Task<T> GetAsync<T>(string name, T defaultValue = default):用于获取具有给定类型T的特征值。允许指定defaultValue特征值为null时返回的值。

  • CheckEnabledAsync(string name):检查是否启用了给定特征。如果特征不为true(启用),则抛出AbpAuthorizationException

定义特征

应该定义一个特征以能够对其进行检查。

FeatureDefinitionProvider

创建一个继承FeatureDefinitionProvider来定义权限的类。

示例:定义权限

using Volo.Abp.Features;namespace FeaturesDemo
{public class MyFeatureDefinitionProvider : FeatureDefinitionProvider{public override void Define(IFeatureDefinitionContext context){var myGroup = context.AddGroup("MyApp");myGroup.AddFeature("MyApp.PdfReporting", defaultValue: "false");myGroup.AddFeature("MyApp.MaxProductCount", defaultValue: "10");}}
}

ABP自动发现此类并注册特征。无需其他配置。

此类通常在Application.Contracts解决方案的项目中创建。

  • Define方法中,您首先需要为您的应用程序/模块添加特征组或获取现有的特征组,然后将特征添加至该组。

  • 第一个特征,命名为MyApp.PdfReporting,是一个boolean特征以false作为默认值。

  • 第二个特征名为MyApp.MaxProductCount,是数字特征,默认值为10

如果没有为当前用户/租户设置其他值,则使用默认值。

其他特征属性

这些最低限度的定义足以使特征系统正常运行,但是您可以为特征指定可选属性

  • DisplayName:可本地化的字符串,将用于在用户界面上显示特征名称。

  • Description:较长的可本地化文字,用于描述特征。

  • ValueType:特征值的类型。可以是实现IStringValueType的类。内置类型:

    • ToggleStringValueType:用于定义true/falseon/offenabled/disabled样式特征。UI上显示一个复选框。

    • FreeTextStringValueType:用于定义自由文本值。UI上显示一个文本框。

    • SelectionStringValueType:用于强制从列表中选择值。UI上显示一个下拉列表。

  • IsVisibleToClients(默认值:true):设置为false可向客户端(浏览器)隐藏此特征的值。与客户共享值可帮助他们根据特征值有条件地显示/隐藏/更改UI部件。

  • Properties:字典,用于设置/获取与此特征相关的任意键值对。这可能是定制的重点。

因此,根据这些描述,最好定义这些特征,如下所示:

using FeaturesDemo.Localization;
using Volo.Abp.Features;
using Volo.Abp.Localization;
using Volo.Abp.Validation.StringValues;namespace FeaturesDemo
{public class MyFeatureDefinitionProvider : FeatureDefinitionProvider{public override void Define(IFeatureDefinitionContext context){var myGroup = context.AddGroup("MyApp");myGroup.AddFeature("MyApp.PdfReporting",defaultValue: "false",displayName: LocalizableString.Create<FeaturesDemoResource>("PdfReporting"),valueType: new ToggleStringValueType());myGroup.AddFeature("MyApp.MaxProductCount",defaultValue: "10",displayName: LocalizableString.Create<FeaturesDemoResource>("MaxProductCount"),valueType: new FreeTextStringValueType(new NumericValueValidator(0, 1000000)));}}
}
  • FeaturesDemoResource是此示例代码中的项目名称。有关本地化系统的详细信息,请参见本地化文档。

  • 第一个特征设置为ToggleStringValueType,第二个特征设置为FreeTextStringValueType,它带有一个数值验证器,允许从01,000,000的值。

记住要在本地化文件中定义本地化键:

"PdfReporting": "PDF Reporting",
"MaxProductCount": "Maximum number of products"

有关本地化系统的详细信息,请参见本地化文档。

特征管理模式

该应用程序启动模板随附了租户管理和特征管理模块。

每当您定义新特征时,它都会在特征管理模式下可用。要打开此模式,请导航至租户管理页面,然后为租户选择Features操作(如果还没有租户,则创建一个新的租户):

[外链图片转存中…(img-D47Bb0uc-1599985883477)]

该动作将打开一个模式来管理所选租户的特征值:

[外链图片转存中…(img-G7IAOqIn-1599985883483)]

因此,您可以启用、禁用和设置租户的值。每当此租户的用户使用该应用程序时,将使用这些值。

请参阅下面的 特征管理 部分,以了解有关管理特征的更多信息。

子特征

特征可能具有子特征。如果要创建仅在启用另一个特征后才可选择的特征,则此特征特别有用。

示例:定义子特征

using FeaturesDemo.Localization;
using Volo.Abp.Features;
using Volo.Abp.Localization;
using Volo.Abp.Validation.StringValues;namespace FeaturesDemo
{public class MyFeatureDefinitionProvider : FeatureDefinitionProvider{public override void Define(IFeatureDefinitionContext context){var myGroup = context.AddGroup("MyApp");var reportingFeature = myGroup.AddFeature("MyApp.Reporting",defaultValue: "false",displayName: LocalizableString.Create<FeaturesDemoResource>("Reporting"),valueType: new ToggleStringValueType());reportingFeature.CreateChild("MyApp.PdfReporting",defaultValue: "false",displayName: LocalizableString.Create<FeaturesDemoResource>("PdfReporting"),valueType: new ToggleStringValueType());reportingFeature.CreateChild("MyApp.ExcelReporting",defaultValue: "false",displayName: LocalizableString.Create<FeaturesDemoResource>("ExcelReporting"),valueType: new ToggleStringValueType());}}
}

上面的示例定义了具有两个子项的Reporting特征PDF ReportingExcel Reporting

更改从属模块的特征定义

FeatureDefinitionProvider派生的类(就像上面的示例一样)也可以获取现有的权限定义(由依赖模块定义)并更改其定义。

示例:操纵现有特征定义

var someGroup = context.GetGroupOrNull("SomeModule");
var feature = someGroup.Features.FirstOrDefault(f => f.Name == "SomeFeature");
if (feature != null)
{feature.Description = ...feature.CreateChild(...);
}

在客户端检查特征

除非您在特征定义上设置IsVisibleToClientsfalse,否则特征值也可在客户端使用。特征值从应用程序配置API公开,可以通过UI上的某些服务使用。

ASP.NET Core MVC / Razor页面用户界面

使用abp.features API获取特征值。

示例:在JavaScript代码中获取特征值

var isEnabled = abp.features.values["MyApp.ExcelReporting"] === "true";
var count = abp.features.values["MyApp.MaxProductCount"];

Angular UI

请参阅Angular UI 的特征文档。

特征管理

特征管理通常由管理员用户使用特征管理模式完成:

[外链图片转存中…(img-RhhSG1XH-1599985883488)]

该模式可用于相关实体,例如多租户应用程序中的租户。要打开它,请导航到“租户管理”页面(对于多租户应用程序),单击“租户”左侧的“ 操作”按钮,然后选择“特征”操作。

如果需要通过代码管理特征,请注入IFeatureManager服务。

示例:为租户启用PDF报告

public class MyService : ITransientDependency
{private readonly IFeatureManager _featureManager;public MyService(IFeatureManager featureManager){_featureManager = featureManager;}public async Task EnablePdfReporting(Guid tenantId){await _featureManager.SetForTenantAsync(tenantId,"MyApp.PdfReporting",true.ToString());}
}

IFeatureManager由特征管理模块定义。它预装有应用程序启动模板。有关更多信息,请参阅特征管理模块文档。

高级主题

特征值提供程序

特征系统是可扩展的。任何派生自FeatureValueProvider(或实现IFeatureValueProvider)的类都可以对特征系统做出贡献。值提供程序负责获取给定特征的当前值

特征值提供程序是逐一执行的。如果其中一个返回非空值,则使用此特征值,并且不执行其他提供程序。

有三个预定义的值提供程序,它们按给定的顺序执行:

  • TenantFeatureValueProvider尝试获取是否为当前租户显式设置了特征值。

  • EditionFeatureValueProvider尝试获取当前版本的特征值。版本ID是从当前的主体标识(ICurrentPrincipalAccessor)和声明名称editionid(定义为AbpClaimTypes.EditionId的常数)获得的。租户管理模块未实现版本。您可以自己实现它,也可以考虑使用ABP 商业版 的SaaS模块。

  • DefaultValueFeatureValueProvider 获取特征的默认值。

您可以通过继承FeatureValueProvider编写自己的提供程序。

示例:使用“SystemAdmin”作为“User_Type”声明值为用户启用所有特征

using System.Threading.Tasks;
using Volo.Abp.Features;
using Volo.Abp.Security.Claims;
using Volo.Abp.Validation.StringValues;namespace FeaturesDemo
{public class SystemAdminFeatureValueProvider : FeatureValueProvider{public override string Name => "SA";private readonly ICurrentPrincipalAccessor _currentPrincipalAccessor;public SystemAdminFeatureValueProvider(IFeatureStore featureStore,ICurrentPrincipalAccessor currentPrincipalAccessor): base(featureStore){_currentPrincipalAccessor = currentPrincipalAccessor;}public override Task<string> GetOrNullAsync(FeatureDefinition feature){if (feature.ValueType is ToggleStringValueType &&_currentPrincipalAccessor.Principal?.FindFirst("User_Type")?.Value == "SystemAdmin"){return Task.FromResult("true");}return null;}}
}

如果提供程序返回null,则执行下一个提供程序。

定义提供程序后,应将其添加到AbpFeatureOptions,如下所示:

Configure<AbpFeatureOptions>(options =>
{options.ValueProviders.Add<SystemAdminFeatureValueProvider>();
});

在您的模块类的ConfigureServices中使用此代码。

特征仓库

IFeatureStore是唯一需要从持久性源(通常是数据库系统)读取特征值的接口。特征管理模块将实现它并预安装在应用程序启动模板中。有关更多信息,请参阅特征管理模块文档。

Abp vnext 特征(Features)相关推荐

  1. Abp VNext 项目创建简介

    文章目录 简介 项目创建 关于 module 项目的简单说明 简单优化项目 1.移动端项目删除 2.*.sln.DotSettings 3.*.HttpApi.Host 的调整 4.*.HttpApi ...

  2. ABP vNext分布式事件总线RabbitMQ注意事项

    [https://docs.abp.io/zh-Hans/abp/latest/Distributed-Event-Bus-RabbitMQ-Integration](ABP vNext官方文档链接) ...

  3. [Abp vNext 源码分析] - 5. DDD 的领域层支持(仓储、实体、值对象)

    一.简要介绍 ABP vNext 框架本身就是围绕着 DDD 理念进行设计的,所以在 DDD 里面我们能够见到的实体.仓储.值对象.领域服务,ABP vNext 框架都为我们进行了实现,这些基础设施都 ...

  4. 基于 abp vNext 和 .NET Core 开发博客项目 - 终结篇之发布项目

    基于 abp vNext 和 .NET Core 开发博客项目 - 终结篇之发布项目 转载于:https://github.com/Meowv/Blog 既然开发完成了,还是拿出来溜溜比较好,本篇是本 ...

  5. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(九)

    基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(九) 转载于:https://github.com/Meowv/Blog 终于要接近尾声了,上一篇基本上将文 ...

  6. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(八)

    基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(八) 转载于:https://github.com/Meowv/Blog 上一篇完成了标签模块和友情链接模块 ...

  7. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(七)

    基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(七) 转载于:https://github.com/Meowv/Blog 上一篇完成了后台分类模块的所有功能 ...

  8. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(六)

    基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(六) 转载于:https://github.com/Meowv/Blog 上一篇完成了博客文章详情页面的数据 ...

  9. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(五)

    基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(五) 转载于:https://github.com/Meowv/Blog 上一篇完成了分类标签友链的列表查询 ...

最新文章

  1. 8086PC机的内存地址空间分配
  2. QEMU — 编译安装指定的版本
  3. 系统部署文档_惊喜!Alibaba架构师终于发布“微服务架构与实践”文档
  4. Pytorch搭建yolo3目标检测平台
  5. 字符编码转换_进制转换(GB2312,GBK,JNI,HexTOStr)
  6. Google Chrome v48.0.2564.
  7. php 获取下拉框选中的文本,jQuery如何获取select选择的文本与值?(代码示例)...
  8. filestream 生成xml 文件时被如何让禁止转义_从Edgecam到PCDMIS,如何将工艺工程师的思想加入质量检测?...
  9. 用promise封装ajax_vue实践---vue结合 promise 封装原生ajax
  10. 学习笔记(02):Python网络编程并发编程-assert断言的用途
  11. C# this关键字的3种用法
  12. Android接口一般定义格式,Android开发规范
  13. Vue组件间常用的通信方式总结
  14. [luogu3198] 玩具装箱
  15. bool类型头文件_C++ Primer Chapter2 变量和基本类型
  16. Mysql DBA 20天速成教程
  17. 全球单片机的主要厂商和主要型号介绍
  18. ServicePack自动补丁更新程序
  19. 清楚易懂的讲解”UV和PV“的含义,以及之间的区别。
  20. namedtuple 具名元组详解

热门文章

  1. python的符号函数得到的数字类型_python-1:Number数字类型 之二 相关函数 int.from_bytes,int.to_bytes()...
  2. 计算机组成原理944考试,郑州大学2019年硕士研究生入学考试 《944计算机组成原理》考试大纲...
  3. python pandas写入_51-python3 pandas读写excel
  4. tensorrt安装_利用TensorRT对深度学习进行加速
  5. 海外精致办公名片展示样机|智能贴图 Mockup名片模板
  6. 多用途管理仪表板UI模板,把枯燥变得简单
  7. 平面设计素材模板| 还在为封面设计烦恼么?
  8. Web UI套件模板|设计师的好帮手
  9. mui获取php表格,Mui table实现数据提取方法
  10. Ubuntu系统下实时监控GPU的温度