ABP框架 - 功能管理
本节内容:
简介
大部分SaaS(多租户)应用有不同功能的版本(包),因此你可以提供不同价格和功能选项给租户(客户)。
ABP提供了一个功能系统,使它易于使用,我们可以定义功能,检查一个功能对于一个租户是否可用,并把功能系统整合到其它ABP概念里(如授权和导航)。
关于 IFeatureValueStore
功能系统使用IFeatureValueStore来获取功能的值。尽管你可以用自己的方式实现它,但在module-zero项目里已经完全实现。如果它没有被实现,NullFeatureValueStore用来为所有功能返回null(这种情况下使用默认功能值)。
功能类型
有两个基本的功能类型。
Boolean 功能
可以是“true”或“false”,一个这种类型的功能可以是启用或禁用(为一个版本或一个租户)。
Value 功能
可以是任意值,它保存和获取一个字符串,数字也保存成字符串。
例如,我们的应用可能是一个任务管理应用,一个月只创建有限的几个任务,假设我们有两个不同的版本/包,有一个允许创建1000个任务每个月,但另一个允许我们创建5000个任务每个月,所以这个功能应当存成值类型,不是简单的true/false。
定义功能
在检查功能前,先要定义它,一个模块可通过继承FeatureProvider类来定义自己的功能,此处,有一个非常简单的功能供应器定义了3个功能:
public class AppFeatureProvider : FeatureProvider
{
public override void SetFeatures(IFeatureDefinitionContext context)
{
var sampleBooleanFeature = context.Create("SampleBooleanFeature", defaultValue: "false");
sampleBooleanFeature.CreateChildFeature("SampleNumericFeature", defaultValue: "");
context.Create("SampleSelectionFeature", defaultValue: "B");
}
}
在创建一个功能供应器之后,我们应当在我们模块的PreInitialize方法里注册它,如下所示:
Configuration.Features.Providers.Add<AppFeatureProvider>();
基本功能属性
一个功能定义要求至少两个属性:
Name:一个唯一名称(字符串),这个功能的标志。
DefaultValue:一个默认值,当我们需要这个功能的值而又不能从当前租户取得时,我们需要一个默认值。
此处,我们定义了一个Boolean功能,名为“SampleBooleanFeature”,默认值为“false”(不可用),同时我们定义了两个值功能(SampleNumericFeature被定义成SampleBooleanFeature的子功能)。
小建议:创建一个字符串常量作为一个功能名,不管在哪里使用都可避免输入错误。
其它功能属性
虽然唯一名称和默认值属性是必须的,但也有一可选的属性,提供细节控制。
- Scope:一个FeatureScopes枚举值,它可以是Edition(如果这个功能只能设置版本级别),Tenant(如果这个功能只能设置租户级别)或All(如果这个功能可设置版本和租户,租户设置会覆盖版本设置)。默认值是All。
- DisplayName:一个本地化的字符串,为用户显示这个功能的名称。
- Description:一个本地化的字符串,为客户显示这个功能的细节描述。
- InputType:这个功能的一个UI输入类型,这个可被定义,当创建一个自动功能屏幕时可以使用它。
- Attribute:一个键值对的用户字典,关联这个功能。
让我们看一下上面那个功能更多的细节定义:
public class AppFeatureProvider : FeatureProvider
{
public override void SetFeatures(IFeatureDefinitionContext context)
{
var sampleBooleanFeature = context.Create(
AppFeatures.SampleBooleanFeature,
defaultValue: "false",
displayName: L("Sample boolean feature"),
inputType: new CheckboxInputType()
); sampleBooleanFeature.CreateChildFeature(
AppFeatures.SampleNumericFeature,
defaultValue: "",
displayName: L("Sample numeric feature"),
inputType: new SingleLineStringInputType(new NumericValueValidator(, ))
); context.Create(
AppFeatures.SampleSelectionFeature,
defaultValue: "B",
displayName: L("Sample selection feature"),
inputType: new ComboboxInputType(
new StaticLocalizableComboboxItemSource(
new LocalizableComboboxItem("A", L("Selection A")),
new LocalizableComboboxItem("B", L("Selection B")),
new LocalizableComboboxItem("C", L("Selection C"))
)
)
);
} private static ILocalizableString L(string name)
{
return new LocalizableString(name, AbpZeroTemplateConsts.LocalizationSourceName);
}
}
注意:输入类型定义不被ABP所用,当创建功能的输入时,它可被应用使用,ABP只是提供基础框架,使它更易于使用。
功能层次
如上面所示的示例功能供应器,一个功能可以有子功能。一个父功能通常定义为Boolean功能,只有在父功能可用时,才能获取子功能。ABP不强制但建议这么做,应用应当小心处理它。
检查功能
我们定义一个功能来检查它的在应用里的值,从而为每个租户允许或阻止一些应用功能。有几种不同的检查方式。
使用RequiresFeature特性
我们可以为一个方法或类使用RequiredFeature,如下所示:
[RequiresFeature("ExportToExcel")]
public async Task<FileDto> GetReportToExcel(...)
{
...
}
只有当前租户(从IAbpSession里获取)的“ExportToExcel”功能可用时,才能执行这个方法,如果不可用,就自动抛出一个AbpAuthorizationException。
当然,RequiresFeature特性应该用在Boolean类型的功能上,否则,你会收到异常。
RequiresFeature特性注意事项
ABP为功能检查使用强大的动态方法拦截,所以在方法上使用RequiresFeature特性有些限制:
- 不能用在private方法上。
- 不能用在静态方法上。
- 不能用在无注入类的方法上(我们必须使用依赖注入)。
同时,可用于:
- 任何通过接口调用的public方法(如通过接口使用应用服务)
- 一个直接通过类引用(如Asp.Net Mvc或Web Api控制器)调用的virtual方法。
- 一个protected virtual方法。
使用 IFeatureChecker
我们可以注入IFeatureChecker,并使用它手动检查一个功能(它被自动注入到应用服务,Mvc和Web Api控制器,并被自动使用)。
IsEnabled
简单的检查一个给定的功能是否可用,如:
public async Task<FileDto> GetReportToExcel(...)
{
if (await FeatureChecker.IsEnabledAsync("ExportToExcel"))
{
throw new AbpAuthorizationException("You don't have this feature: ExportToExcel");
} ...
}
IsEnabledAsync和其它方法同样有异步版本。
当然,IsEnabled方法应当被Boolean类型的功能使用,否则,你会得到异常。
如果你只是想检查一个功能,并抛出异常,如上面例子所示那样,你可以使用CheckEnabled方法。
GetValue
获取一个值类型功能的当前值,例如:
var createdTaskCountInThisMonth = GetCreatedTaskCountInThisMonth();
if (createdTaskCountInThisMonth >= FeatureChecker.GetValue("MaxTaskCreationLimitPerMonth").To<int>())
{
throw new AbpAuthorizationException("You exceed task creation limit for this month, sorry :(");
}
FeatureChecker方法也提供了为一个指定tenantId工作的功能,不只是为当前tenantId。
客户端
在客户端(Javascript),我们可以使用abp.features命名空间来获取功能的当前值。
isEnabled
var isEnabled = abp.features.isEnabled('SampleBooleanFeature');
getValue
var value = abp.features.getValue('SampleNumericFeature');
功能管理器
如果你需要用到功能的定义,你可以注入IFeatureManager并使用它。
对版本的一个提示
ABP框架没有一个内容的版本系统,因为如此一个系统需要一个数据库(存储版本,版本功能,租户版本映射...),因此,版本系统在module zero里实现,你可以很容易的使用它并获取一个版本系统,或者你自己实现。
ABP框架 - 功能管理的更多相关文章
- ABP框架 - 设置管理
文档目录 本节内容: 简介 关于ISettingStore 定义设置 setting scope(设置范围) 重写设置定义 获取设置值 服务端 客户端 修改设置 关于缓存 简介 每个应用必需存储一些设 ...
- 中小研发团队架构实践之生产环境诊断工具WinDbg 三分钟学会.NET微服务之Polly 使用.Net Core+IView+Vue集成上传图片功能 Fiddler原理~知多少? ABP框架(asp.net core 2.X+Vue)模板项目学习之路(一) C#程序中设置全局代理(Global Proxy) WCF 4.0 使用说明 如何在IIS上发布,并能正常访问
中小研发团队架构实践之生产环境诊断工具WinDbg 生产环境偶尔会出现一些异常问题,WinDbg或GDB是解决此类问题的利器.调试工具WinDbg如同医生的听诊器,是系统生病时做问题诊断的逆向分析工具 ...
- ABP开发框架前后端开发系列---(9)ABP框架的权限控制管理
在前面两篇随笔<ABP开发框架前后端开发系列---(7)系统审计日志和登录日志的管理>和<ABP开发框架前后端开发系列---(8)ABP框架之Winform界面的开发过程>开始 ...
- ABP理论学习之功能管理
返回总目录 本篇目录 介绍 功能类型 定义功能 检查功能 功能管理者 版本说明 介绍 大多数的Saas(多租户)应用都有不同 功能的 版本(包).因此,他们可以给租户(客户)提供不同的 价格和功能选项 ...
- ABP框架中一对多,多对多关系的处理以及功能界面的处理(1)
在我们开发业务的时候,一般数据库表都有相关的关系,除了单独表外,一般还包括一对多.多对多等常见的关系,在实际开发过程中,需要结合系统框架做对应的处理,本篇随笔介绍基于ABP框架对EF实体.DTO关系的 ...
- ABP框架实践基础篇之开发UI层
返回总目录<一步一步使用ABP框架搭建正式项目系列教程> 说明 其实最开始写的,就是这个ABP框架实践基础篇.在写这篇博客之前,又回头复习了一下ABP框架的理论,如果你还没学习,请查看AB ...
- 一步一步使用ABP框架搭建正式项目系列教程之本地化详解
返回总目录<一步一步使用ABP框架搭建正式项目系列教程> 本篇目录 扯扯本地化 ABP中的本地化 小结 扯扯本地化 本节来说说本地化,也有叫国际化.全球化的,不管怎么个叫法,反正道理都是一 ...
- 详解ABP框架的多租户
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:ABP框架对多租户场景提供了很好的支持,内建了多租户的处理机制,今天我们来深入解析一下 ...
- ABP框架详解(二)AbpKernelModule
AbpKernelModule类是Abp框架自己的Module,它也跟所有其他的Module一样继承自AbpModule,重写PreInitialize,Initialize,PostInitiali ...
随机推荐
- JS调用Android、Ios原生控件
在上一篇博客中已经和大家聊了,关于JS与Android.Ios原生控件之间相互通信的详细代码实现,今天我们一起聊一下JS调用Android.Ios通信的相同点和不同点,以便帮助我们在进行混合式开发时, ...
- “不给力啊,老湿!”:RSA加密与破解
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 加密和解密是自古就有技术了.经常看到侦探电影的桥段,勇敢又机智的主角,拿着一长串毫 ...
- 标准产品+定制开发:专注打造企业OA、智慧政务云平台——山东森普软件,交付率最高的技术型软件公司
一.公司简介山东森普信息技术有限公司(以下简称森普软件)是一家专门致力于移动互联网产品.企业管理软件定制开发的技术型企业.公司总部设在全国五大软件园之一的济南齐鲁软件园.森普SimPro是由Simpl ...
- HTML5 localStorage本地存储
介绍 localStorage(本地存储)的使用方式.包括对存储对象的添加.修改.删除.事件触发等操作. 目录 1. 介绍 1.1 说明 1.2 特点 1.3 浏览器最小版本支持 1.4 适合场景 2 ...
- Vue-Router 页面正在加载特效
Vue-Router 页面正在加载特效 如果你在使用 Vue.js 和 Vue-Router 开发单页面应用.因为每个页面都是一个 Vue 组件,你需要从服务器端请求数据,然后再让 Vue 引擎来渲染 ...
- H5坦克大战之【玩家控制坦克移动2】
周一没有看圣诞大战,这几天比较忙也没有看赛后的报道,今天就先不扯NBA,随便扯扯自己.昨天在电脑里找东西的时候翻到以前兼职健身教练时的照片,思绪一下子回到学生时代,脑子久久换不过来.现在深深觉得健身和 ...
- Spring Enable annotation – writing a custom Enable annotation
原文地址:https://www.javacodegeeks.com/2015/04/spring-enable-annotation-writing-a-custom-enable-annotati ...
- 接口--interface
“interface”(接口)关键字使抽象的概念更深入了一层.我们可将其想象为一个“纯”抽象类.它允许创建者规定一个类的基本形式:方法名.自变量列表以及返回类型,但不规定方法主体.接口也包含了基本数据 ...
- 【夯实PHP基础】UML序列图总结
原文地址 序列图主要用于展示对象之间交互的顺序. 序列图将交互关系表示为一个二维图.纵向是时间轴,时间沿竖线向下延伸.横向轴代表了在协作中各独立对象的类元角色.类元角色用生命线表示.当对象存在时,角色 ...
- Android Studio切换为eclipse的快捷键之后还是有区别的部分快捷键
Android Studio Eclipse 把代码提示换成了Class Name Completion, 快捷键是Ctrl+Alt+Space(空格键). 代码提示快捷键Alt+/, ...