ABP官方文档翻译 4.5 特征管理
特征管理
介绍
大多数的Saas(多租户)应用有不同的版本(包),不同的版本有不同的特征。因此,他们可以给他们的租户(客户)提供不同的价格和特征选项。
ABP提供了特征系统,使特征管理变得容易。我们可以定义特征,检查一个特征对租户是否可用,集成特征系统到其他ABP概念中(如授权和导航)。
关于IFeatureValueStore
特征系统使用IFeatureValueStore获取特征值。你可以按照自己的方式实现,但在module-zero工程里已完全实现。如果它没被实现,将会使用NullFeatureValueStore,所有的特征它都返回null(这种情况下使用默认的特征值)。
特征类型
Boolean特征
可以为“true”或“false”。这种特征类型可以为enabled或disabled(对于一个版本或一个租户)。
Value特征
可以为任意的值。它存储并提取字符串,数字也可以以字符串的形式存储。
例如,我们有一个task管理应用,这个应用在一个月内创建task的数量有限制。比方说,我们有两种不同的版本/包;一种允许一个月创建1000个任务,另一个允许创建5000个任务。所以,这种特征应该使用值存储,而不是简单的true/false。
定义特征
特征需先声明再检查。一个模块可以通过从FeatureProvider类继承来定义它自己的特征。这里,一个特征提供者定义了三个特征:
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:一个唯一的名称(字符串)来标识特征。
- Default Value:一个默认值。当我们需要特征值的时候使用这个值,对于当前租户它是不可用的。
这里,我们定义了一个名为“SampleBooleanFeature”的布尔特征,默认值为“false”(不可用)。我们也定义了两个值特征(SampleNumericFeature定义为SampleBooleanFeature的子特征)。
小提示:为特征名字创建静态字符串,并在任何需要的地方使用它,可以避免输入错误。
其他特征属性
除了唯一名称和默认值属性是必须的,还有其他一些可选属性用来更详细的控制:
- Scope:FeatureScopes枚举的一个值。它可以为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: "",
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(...)
{
...
}
只有“ExportToExcel”对当前租户(当前租户从IAbpSession中获得)可用时,这个方法才能执行。如果它是不可用的,会自动抛出AbpAuthorizationException。
当然,RequiresFeature特性应用于boolean类型特征。否则会抛出异常。
RequiresFeature特性注意点
Abp使用动态方法拦截来实现特征检查。所以,对于使用RequiresFeature特性的方法有些限制:
- 不能用于私有方法。
- 不能用于静态方法。
- 不能用于non-injected类的方法(我们必须使用依赖注入)。
另外,
- 可以用于任何public方法,如果这个方法是通过接口调用(如应用服务通过接口使用)。
- 如果直接从引用类调用,方法需要为virtual。(如ASP.NET MVC或Web API控制器)。
- 如果方法为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官方文档翻译 4.5 特征管理的更多相关文章
- ABP官方文档翻译 2.5 设置管理
设置管理 介绍 关于 ISettingStore 定义设置 设置范围 重写设置定义 获取设置值 服务端 客户端 更改设置 关于缓存 介绍 每个应用都需要存储设置,并且在应用的某些地方需要使用这些设置. ...
- ABP官方文档翻译 10.1 ABP Nuget包
ABP Nuget包 Packages Abp Abp.AspNetCore Abp.Web.Common Abp.Web Abp.Web.Mvc Abp.Web.Api Abp.Web.Api.OD ...
- ABP官方文档翻译 6.1.2 MVC视图
ASP.NET MVC 视图 介绍 AbpWebViewPage基类 介绍 ABP通过Abp.Web.Mvc nuget包集成到MVC视图.你可以如往常一样创建正常的MVC视图. AbpWebView ...
- ABP官方文档翻译 0.0 ABP官方文档翻译目录
一直想学习ABP,但囿于工作比较忙,没有合适的契机,当然最重要的还是自己懒.不知不觉从毕业到参加工作七年了,没留下点儿什么,总感觉很遗憾,所以今天终于卯足劲鼓起勇气开始写博客.有些事能做的很好,但要跟 ...
- ABP官方文档翻译 6.7 CSRF/XSRF保护
CSRF/XSRF保护 介绍 HTTP动词 非浏览器客户端 ASP.NET MVC 特征 集成 布局视图 配置 ASP.NET Web API 特征 集成 集成到ASP.NET MVC客户端 集成到其 ...
- ABP官方文档翻译 3.6 工作单元
工作单元 介绍 ABP中的连接和事务管理 传统的工作单元方法 控制工作单元 UnitOfWork特性 IUnitOfWorkManager 工作单元详情 禁用工作单元 无事务工作单元 一个工作单元方法 ...
- ABP官方文档翻译 7.1 后台Jobs和Workers
后台Jobs和Workers 介绍 后台Jobs 关于Job持久化 创建后台Job 在队列中添加一个新Job 默认的后台Job管理器 后台Job存储 配置 禁用Job执行 异常处理 Hangfire集 ...
- ABP官方文档翻译 4.4 授权
授权 介绍 关于IPermissionChecker 定义权限 检查权限 使用AbpAuthorize特性 AbpAuthorize特性注意点 抑制授权 使用IPermissionChecker 在R ...
- ABP官方文档翻译 1.1 介绍
介绍 介绍 快速示例 其他 启动模板 如何使用 介绍 我们通常会根据不同的需求来创建不同的应用程序.但是对于一些通用相似的结构总是一遍又一遍的实现,至少在某种程度上是这样的.常见的通用模块如授权.验证 ...
随机推荐
- CTF---安全杂项入门第一题 丘比龙的最爱
丘比龙的最爱分值:10 来源: 2014HCTF 难度:易 参与人数:4498人 Get Flag:1366人 答题人数:1384人 解题通过率:99% 传说,丘比龙是丘比特的弟弟,丘比龙是一只小爱神 ...
- SPRING BOOT跨域访问处理
尊重原创:http://blog.csdn.net/ruiguang21/article/details/77878933 问题场景:由于项目中使用到跨域访问,今天也得到高人指点,所以写出来分享给大家 ...
- 初步了解关于js跨域问题-jsonp
js跨域问题是指在js在不同的域中进行数据传输或者数据通信,比如通过ajax向不同的域请求数据(说到ajax,不可避免的就会遇到两个问题:一是ajax是如何传递数据的?二是ajax是如何实现跨域的?) ...
- [国嵌攻略][071][Coredump故障分析]
Core Dump定义 Core Dump又叫核心转存.当程序在运行过程中发生异常,Linux系统可以把程序出错时的内存内容存储在一个core文件中,这个过程叫Core Dump. Core Dump ...
- [C#]使用控制台获取天气预报
本例子主要是使用由中央气象局网站(http://www.nmc.gov.cn)提供的JSON API,其实现思路如下: 1.访问获取省份(包含直辖市.自治区等,以下简称省份)的网址(http://ww ...
- thinkPHP中_initialize方法实例分析
子类的_initialize方法自动调用父类的_initialize方法. 而php的构造函数construct,如果要调用父类的方法,必须在子类构造函数显示调用parent::__construct ...
- 【开发技术】Beyond Compare
黑色表示左右两侧的文件(夹)是一样的; 紫色表示右(左)侧是完全没有的,这时我们右击这个文件(夹),选择“复制到右(左)侧”即可: 红色表示两边都有这个文件(夹),但不完全相同,这时你就要权衡一下修改 ...
- mysql 两个时间段的差,可以是秒,天,星期,月份,年...
SELECT TIMESTAMPDIFF(SECOND, now(), "2012-11-11 00:00:00") 语法为:TIMESTAMPDIFF(unit,datetime ...
- 策略模式--List排序
需求:根据姓名进行排序,升序或者降序,如果名字一样,就按照id升序排序,用策略模式 步骤一: 定义一个Person对象 public class Person { private Integer id ...
- underscore.js 源码阅读 一 整体结构
// 整个underscore的实现包在一个立即执行函数中,避免污染全局对象 // 通过call(this)来入全局变量 (function() { // 缓存this var root = this ...