ABP理论学习之功能管理
本篇目录
介绍###
大多数的Saas(多租户)应用都有不同 功能的 版本(包)。因此,他们可以给租户(客户)提供不同的 价格和功能选项。
ABP提供了功能系统使得这个更简单。我们可以 定义功能,然后检查某个功能是否对一个租户 开启了,最后将功能系统 集成到其他的ABP概念中(如权限和菜单)。
关于IFeatureValueStore
功能系统使用了IFeatureValueStore来获得功能的值。虽然你可以用自己的方式实现该接口,但是它已经完全实现在了 module-zero项目中。如果没有实现该接口,那么默认会使用NullFeatureValueStore对所有的功能返回null(此时使用默认的功能值)。
功能类型###
有两种基本功能类型。
布尔功能
可以是"true"或"false"。这种类型的功能(对于一个版本或者一个租户)可能是开启的或者 关闭的。
值功能
可以是任意值。虽然它是以字符串存储和检索的,但是数值也可以轻松地存储为字符串。
比如,我们的应用程序可能是一个任务管理应用,我们可能在一个月内对于创建任务会有限制。假如说我们有两个不同的版本:一个版本每个月允许创建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: "10");
context.Create("SampleSelectionFeature", defaultValue: "B");
}
}
创建功能提供者之后,我们应该在模块的PreInitialize方法中注册,如下所示:
Configuration.Features.Providers.Add<AppFeatureProvider>();
基本功能属性
一个功能的定义至少要求两个属性:
- Name:识别该功能唯一的名字(字符串)。
- DefaultValue:默认值。当我们需要该功能的值时会用到该属性,而且对于当前的租户不可用。
上面的代码样例中,我们定义了一个名为"SampleBooleanFeature"布尔功能,它的默认值是"false"(不可用)。我们也定义了两个值功能(SampleNumericFeature定义为SampleBooleanFeature的孩子)。
提示:为功能名称创建一个常量字符串,然后在任何地方使用时会防止拼写失误。
其他功能属性
虽然对于ABP来说一个唯一的名称和默认值属性已经足够了,但是对于细节的控制还有许多其他的功能属性。
- Scope:FeatureScope枚举值之一。它可以是Edition(如果只为版本级别设置该功能), Tenant(如果只为租户级别设置该功能),或者 All(如果为版本和租户都可以设置该功能,这种情况下,租户的设置会覆盖版本的设置)。默认值是All。
- DisplayName:给用户显示该功能名称的本地化字符串。
- Description:给用户显示该功能细节描述的本地化字符串。
- InputType:该功能的UI输入类型。
- Attributes:任意的自定义键值对字典,可以和该功能关联起来。
让我们看一下该功能的细节定义:
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: "10",
displayName: L("Sample numeric feature"),
inputType: new SingleLineStringInputType(new NumericValueValidator(1, 1000000))
);
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没有使用这里的InputType。当为功能创建输入时,应用程序会使用它们。ABP只是提供了这些选项使得它更容易。
功能层次
正如样例功能提供者所示,一个功能可以有子功能。一个父母功能一般定义为 布尔功能。只有父母功能可用时,孩子功能才可用。ABP不强制这样做,但是建议这样做。
检查功能###
使用RequireFeature特性
我们可以为方法或类使用RequiredFeature特性,如下所示:
[RequiresFeature("ExportToExcel")]
public async Task<FileDto> GetReportToExcel(...)
{
...
}
该方法只有在"ExportToExcel"功能对当前租户开启时才会执行(当前租户从IAbpSession中获得)。如果没有开启该功能,那么就会自动抛出 AbpAuthorizationException。
当然,RequiresFeature特性应该用于布尔类型功能。否则,你会得到异常。
RequiresFeature特性注意点
ABP对于功能检查使用了强大的动态方法拦截(interception)。因此,为方法使用RequiresFeature特性时有一些限制条件:
- 不能用于私有方法。
- 不能用于静态方法。
- 不能用于非注入类的方法(我们必须使用DI)。
此外,
- 如果该方法是通过一个接口(如应用服务通过接口调用)调用的,那么我们可以将它用于任何 public的方法。
- 如果一个方法直接从类的引用调用(如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方法应该用于布尔类型功能。否则可能会抛异常。
如果你只想检查一个功能,然后抛出例子中的异常,那么你只需要使用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方法也有对于特定租户的重载,不仅仅只对于当前的租户。
客户端
在客户端,我们使用abp.features命名空间来获得该功能的当前值。
isEnabled
var isEnabled = abp.features.isEnabled('SampleBooleanFeature');
getValue
var value = abp.features.getValue('SampleNumericFeature');
功能管理者###
如果需要定义功能,可以注入并使用IFeatureManager。
版本说明###
ABP没有内置的版本系统,因为这么个系统要求数据库(存储版本,版本功能,租户-版本映射等等)。因此,版本系统实现在了module-zero中了。使用它你可以轻松地拥有一个版本系统,要不然你可以自己实现。
ABP理论学习之功能管理的更多相关文章
- ABP理论学习之设置管理
返回总目录 本篇目录 介绍 定义设置 获取设置值 更改设置 关于缓存 介绍 每个应用程序都需要存储一些设置信息,然后在应用程序中的某个地方使用这些设置.ABP提供了健壮的基础设施来存储或检索服务端和客 ...
- ABP框架 - 功能管理
文档目录 本节内容: 简介 关于 IFeatureValueStore 功能类型 Boolean 功能 Value 功能 定义功能 基本功能属性 其它功能属性 功能层次 检查功能 使用Requires ...
- ABP理论学习之MVC视图
返回总目录 本篇目录 介绍 AbpWebViewPage基类 介绍 ABP通过Abp.Web.Mvc Nuget包集成了MVC视图.因此你可以像常规那样创建MVC视图. AbpWebViewPage基 ...
- ABP理论学习之Javascript API(理论完结篇)
返回总目录 本篇目录 Ajax Notification Message UI block和busy 事件总线 Logging 其他工具功能 说在前面的话 不知不觉,我们送走了2015,同时迎来了20 ...
- AspnetBoilerplate (ABP) Organization Units 组织结构管理
ABP是一个成熟的.NET框架,功能完善.目前由于项目需要正在自学中. ABP对于组织节点管理这一基本上每个项目都要反复重复开发的内容,进行了自己的实现. 主要包括这些常用功能: 多租户 树结构管理的 ...
- X-Admin&ABP框架开发-设置管理
在网站开发中,设置是不可缺少的一环,如用户设置.系统设置.甚至是租户设置等.ABP对于设置的管理已经做了很好的处理,我们可以借助巨人的力量来完成我们的冒险. ABP官网地址:https://aspne ...
- Asp.Net Core 项目实战之权限管理系统(6) 功能管理
0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...
- ABP理论学习之仓储
返回总目录 本篇目录 IRepository接口 查询 插入 更新 删除 其他 关于异步方法 仓储实现 管理数据库连接 仓储的生命周期 仓储最佳实践 Martin Fowler对仓储的定义 位于领域层 ...
- Xianfeng轻量级Java中间件平台:功能管理
功能管理:从功能类型来看,不属于用户使用的功能,而属于系统维护使用的功能,因为对于用户来说,是不可见的.功能管理的作用是定义一套规则,用来处理权限等业务,比如常见的菜单权限控制.按钮权限控制等情景 在 ...
随机推荐
- Js 日期转换函数(UTC时间转换及日期想加减)
IOS上Js日期转换中new Date("yyyy-mm-dd")不能正常工作,必须使用new Date("yyyy/MM/dd"); 日期相加减: Date. ...
- 【leetcode】Palindrome Number
题目简述: Determine whether an integer is a palindrome. Do this without extra space. Some hints: Could n ...
- [OPENCV] 第一个程序 识别颜色
它可以鉴别出图像中含有给定颜色的所有像素,该算法输入的是图像以及颜色,并返回表示含有指定颜色的像素的二值图像.该算法还需要指定另外一个参数,即对颜色偏差的容忍度. 实现效果 实现后 #include ...
- Xocde一次版本升级遇到的问题 (Code Sign Error)
因为Xcode对ios版本的支持问题,我对XCode进行了一次升级,导致原来还好的项目代码出现了编译时错误. Code Sign Error failed with exit code 1 问题就在于 ...
- font-family字体总结
宋体 SimSun黑体 SimHei微软雅黑 Microsoft YaHei微软正黑体 Microsoft JhengHei新宋体 NSimSun新细明体 PMingLiU细明体 MingLiU标楷体 ...
- BZOJ 1176 [Balkan2007]Mokia ——CDQ分治
[题目分析] 同BZOJ2683,只需要提前处理s对结果的影响即可. CDQ的思路还是很清晰的. 排序解决一维, 分治时间, 树状数组解决一维. 复杂度是两个log [代码] #include < ...
- 矩阵快速幂 HDU 4565 So Easy!(简单?才怪!)
题目链接 题意: 思路: 直接拿别人的图,自己写太麻烦了~ 然后就可以用矩阵快速幂套模板求递推式啦~ 另外: 这题想不到或者不会矩阵快速幂,根本没法做,还是2013年长沙邀请赛水题,也是2008年Go ...
- iOS APP性能优化
:应用启动时间 应用启动时,只加载启动相关的资源和必须在启动时加载的资源. :本地图片加载方式 本地图片加载常用方法有两种: a. [UIImage imageNamed:@"xx.png& ...
- HashMap的内部实现机制,Hash是怎样实现的,什么时候ReHash
1.HashMap的内部实现机制 HashMap是对数据结构中哈希表(Hash Table)的实现,Hash表又叫散列表.Hash表是根据关键码Key来访问其对应的值Value的数据结构,它通过一个映 ...
- [软件推荐]快速文件复制工具(Limit Copy) V4.0 绿色版
快速文件复制工具(Limit Copy)绿色版是一款智能变频超快复制绿色软件. 快速文件复制工具(Limit Copy)功能比较完善,除了文件复制还可以智能变频,直接把要复制的文件拖入窗口即可,无需手 ...