特征管理

介绍

  大多数的Saas(多租户)应用有不同的版本(包),不同的版本有不同的特征。因此,他们可以给他们的租户(客户)提供不同的价格和特征选项。

  ABP提供了特征系统,使特征管理变得容易。我们可以定义特征,检查一个特征对租户是否可用,集成特征系统到其他ABP概念中(如授权和导航)。

关于IFeatureValueStore

  特征系统使用IFeatureValueStore获取特征值。你可以按照自己的方式实现,但在module-zero工程里已完全实现。如果它没被实现,将会使用NullFeatureValueStore,所有的特征它都返回null(这种情况下使用默认的特征值)。

特征类型

Boolean特征

  可以为“true”或“false”。这种特征类型可以为enableddisabled(对于一个版本或一个租户)。

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 特征管理的更多相关文章

  1. ABP官方文档翻译 2.5 设置管理

    设置管理 介绍 关于 ISettingStore 定义设置 设置范围 重写设置定义 获取设置值 服务端 客户端 更改设置 关于缓存 介绍 每个应用都需要存储设置,并且在应用的某些地方需要使用这些设置. ...

  2. 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 ...

  3. ABP官方文档翻译 6.1.2 MVC视图

    ASP.NET MVC 视图 介绍 AbpWebViewPage基类 介绍 ABP通过Abp.Web.Mvc nuget包集成到MVC视图.你可以如往常一样创建正常的MVC视图. AbpWebView ...

  4. ABP官方文档翻译 0.0 ABP官方文档翻译目录

    一直想学习ABP,但囿于工作比较忙,没有合适的契机,当然最重要的还是自己懒.不知不觉从毕业到参加工作七年了,没留下点儿什么,总感觉很遗憾,所以今天终于卯足劲鼓起勇气开始写博客.有些事能做的很好,但要跟 ...

  5. ABP官方文档翻译 6.7 CSRF/XSRF保护

    CSRF/XSRF保护 介绍 HTTP动词 非浏览器客户端 ASP.NET MVC 特征 集成 布局视图 配置 ASP.NET Web API 特征 集成 集成到ASP.NET MVC客户端 集成到其 ...

  6. ABP官方文档翻译 3.6 工作单元

    工作单元 介绍 ABP中的连接和事务管理 传统的工作单元方法 控制工作单元 UnitOfWork特性 IUnitOfWorkManager 工作单元详情 禁用工作单元 无事务工作单元 一个工作单元方法 ...

  7. ABP官方文档翻译 7.1 后台Jobs和Workers

    后台Jobs和Workers 介绍 后台Jobs 关于Job持久化 创建后台Job 在队列中添加一个新Job 默认的后台Job管理器 后台Job存储 配置 禁用Job执行 异常处理 Hangfire集 ...

  8. ABP官方文档翻译 4.4 授权

    授权 介绍 关于IPermissionChecker 定义权限 检查权限 使用AbpAuthorize特性 AbpAuthorize特性注意点 抑制授权 使用IPermissionChecker 在R ...

  9. ABP官方文档翻译 1.1 介绍

    介绍 介绍 快速示例 其他 启动模板 如何使用 介绍 我们通常会根据不同的需求来创建不同的应用程序.但是对于一些通用相似的结构总是一遍又一遍的实现,至少在某种程度上是这样的.常见的通用模块如授权.验证 ...

随机推荐

  1. Java Socket获取本机的InetAddress实例

    package com.immooc;/* * InetAddress类 */import java.net.InetAddress;import java.net.UnknownHostExcept ...

  2. Vjios P1736 铺地毯【暴力,思维】

    铺地毯 描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有n张地毯,编号从1到n.现在将这些地毯按照编号从小到大的顺序平行于坐标轴 ...

  3. IE8兼容border-radius.

    我们知道,CSS3新增的很多简洁优美的属性,比如border-radius.box-shadow.border-image.gradients.RGBA...因为这些属性的出现,我们可以很方便的就写会 ...

  4. ==和equals详解+例子

    一开始遇见==和equals我也是分不清,后来看了很多博客,收益匪浅, 担心以后给忘了,所以写下这个,以后复习可以用. (有哪里写得不对的,希望可以留言帮忙改进,大家一起共同进步) 一.Java数据类 ...

  5. MySQL事务隔离级别的实现原理

    回顾 在MySQL的众多存储引擎中,只有InnoDB支持事务,所有这里说的事务隔离级别指的是InnoDB下的事务隔离级别. 读未提交:一个事务可以读取到另一个事务未提交的修改.这会带来脏读.幻读.不可 ...

  6. 语句、变量等js最基本知识

    JavaScript的最为基本知识 1语法 js是区分大小写的:标识符就是指变量.函数.属性的名字或者是参数,标识符可以是字母,下划线,美元符号,数字,注意第一个不能是数字:js采用的是驼峰大小格式: ...

  7. Hive 多分隔符的使用 (转载)

    方法一)通过org.apache.hadoop.hive.contrib.serde2.RegexSerDe格式的serde. 1) 建表语句 #指定以^|~作为分隔符 CREATE TABlE ta ...

  8. python文件操作总结

    python中对文件.文件夹(文件操作函数)的操作需要涉及到os模块和shutil模块. 得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd() 返回指定目录下的所有文件和目 ...

  9. fhs文件系统层级结构

    文件系统:操作系统用于明确存储设备或分区上的文件的方法和数据结构:层次化管理文件的结构就是文件系统: linux层次化文件结构,倒树状结构文件结构        FHS  filesystem hie ...

  10. 006-接收键盘的输入(read)

    read  -ptns   变量名 -p 在等待read输入的时候,显示的提示信息 -t 秒数,read等待用户输入的时间 -n read接收用户输入的字符数,只接收指定字符数,就会执行 -s 隐藏输 ...