Abp vnext 特征(Features)
文章目录
- 简介
- 检查特征
- 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
方法(返回一个Task
或Task<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
/false
,on
/off
,enabled
/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
,它带有一个数值验证器,允许从0
到1,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 Reporting和Excel Reporting。
更改从属模块的特征定义
从FeatureDefinitionProvider
派生的类(就像上面的示例一样)也可以获取现有的权限定义(由依赖模块定义)并更改其定义。
示例:操纵现有特征定义
var someGroup = context.GetGroupOrNull("SomeModule");
var feature = someGroup.Features.FirstOrDefault(f => f.Name == "SomeFeature");
if (feature != null)
{feature.Description = ...feature.CreateChild(...);
}
在客户端检查特征
除非您在特征定义上设置IsVisibleToClients
为false
,否则特征值也可在客户端使用。特征值从应用程序配置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)相关推荐
- Abp VNext 项目创建简介
文章目录 简介 项目创建 关于 module 项目的简单说明 简单优化项目 1.移动端项目删除 2.*.sln.DotSettings 3.*.HttpApi.Host 的调整 4.*.HttpApi ...
- ABP vNext分布式事件总线RabbitMQ注意事项
[https://docs.abp.io/zh-Hans/abp/latest/Distributed-Event-Bus-RabbitMQ-Integration](ABP vNext官方文档链接) ...
- [Abp vNext 源码分析] - 5. DDD 的领域层支持(仓储、实体、值对象)
一.简要介绍 ABP vNext 框架本身就是围绕着 DDD 理念进行设计的,所以在 DDD 里面我们能够见到的实体.仓储.值对象.领域服务,ABP vNext 框架都为我们进行了实现,这些基础设施都 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - 终结篇之发布项目
基于 abp vNext 和 .NET Core 开发博客项目 - 终结篇之发布项目 转载于:https://github.com/Meowv/Blog 既然开发完成了,还是拿出来溜溜比较好,本篇是本 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(九)
基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(九) 转载于:https://github.com/Meowv/Blog 终于要接近尾声了,上一篇基本上将文 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(八)
基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(八) 转载于:https://github.com/Meowv/Blog 上一篇完成了标签模块和友情链接模块 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(七)
基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(七) 转载于:https://github.com/Meowv/Blog 上一篇完成了后台分类模块的所有功能 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(六)
基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(六) 转载于:https://github.com/Meowv/Blog 上一篇完成了博客文章详情页面的数据 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(五)
基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(五) 转载于:https://github.com/Meowv/Blog 上一篇完成了分类标签友链的列表查询 ...
最新文章
- 8086PC机的内存地址空间分配
- QEMU — 编译安装指定的版本
- 系统部署文档_惊喜!Alibaba架构师终于发布“微服务架构与实践”文档
- Pytorch搭建yolo3目标检测平台
- 字符编码转换_进制转换(GB2312,GBK,JNI,HexTOStr)
- Google Chrome v48.0.2564.
- php 获取下拉框选中的文本,jQuery如何获取select选择的文本与值?(代码示例)...
- filestream 生成xml 文件时被如何让禁止转义_从Edgecam到PCDMIS,如何将工艺工程师的思想加入质量检测?...
- 用promise封装ajax_vue实践---vue结合 promise 封装原生ajax
- 学习笔记(02):Python网络编程并发编程-assert断言的用途
- C# this关键字的3种用法
- Android接口一般定义格式,Android开发规范
- Vue组件间常用的通信方式总结
- [luogu3198] 玩具装箱
- bool类型头文件_C++ Primer Chapter2 变量和基本类型
- Mysql DBA 20天速成教程
- 全球单片机的主要厂商和主要型号介绍
- ServicePack自动补丁更新程序
- 清楚易懂的讲解”UV和PV“的含义,以及之间的区别。
- namedtuple 具名元组详解
热门文章
- python的符号函数得到的数字类型_python-1:Number数字类型 之二 相关函数 int.from_bytes,int.to_bytes()...
- 计算机组成原理944考试,郑州大学2019年硕士研究生入学考试 《944计算机组成原理》考试大纲...
- python pandas写入_51-python3 pandas读写excel
- tensorrt安装_利用TensorRT对深度学习进行加速
- 海外精致办公名片展示样机|智能贴图 Mockup名片模板
- 多用途管理仪表板UI模板,把枯燥变得简单
- 平面设计素材模板| 还在为封面设计烦恼么?
- Web UI套件模板|设计师的好帮手
- mui获取php表格,Mui table实现数据提取方法
- Ubuntu系统下实时监控GPU的温度