ABP框架中存在一个Feature的特性,功能和设计思路非常类似于框架中的Authorization功能,都是来控制用户是否能够继续操作某项功能,不同点在于Authorization默认是应用在IApplicationService上控制用户或者其所属租户是否具有权限访问服务,而Feature应用更为广泛可以控制访问任意类型,但是控制方式更为单纯只有开关(Enable或者Disable),而且是无法控制具体用户的,只能是某些指定的全局范围内。注意Feature也是有父子关系的,只有父Feature可用,子Feature才有意义。
如上所述所有的父Feature主要开和关两种值,所以为了简单起见,父Feature有"true"和"false"两个字符串为可能值,定义一个Feature特别简单,在任何地方定义一个继承自FeatureProvider的类型,并重写
void SetFeatures(IFeatureDefinitionContext context)
方法,在方法体中调用IFeatureDefinitionContext的Create方法创建一个Name具有唯一性的Feature。在任意一个自定义的AbpModule类中通过StartupConfiguration引用到FeatureConfiguration,FeatureConfiguration的Providers属性就是用来注册所有FeatureProvider的
internal class FeatureConfiguration : IFeatureConfiguration
{
public ITypeList<FeatureProvider> Providers { get; private set; } public FeatureConfiguration()
{
Providers = new TypeList<FeatureProvider>();
}
}
在系统启动阶段会使用Ioc容器实例化一个单例的FeatureManager,调用其void Initialize()方法将FeatureConfiguration中存储的所有FeatureProvider类型注册到FeatureManager实例所包含的的一个字典变量中,同时会递归的将Feature自身的子Feature包含到字典中。后面所有需要Check Feature的时候都可以通过FeatureManager的实例根据Feature的具有唯一性的Name获得指定的Feature从而判断是否启用。
定义并注册一个Feature很简单,在项目中使用Feature也同样很简单,之前的博文中提到框架中有一个FeatureInterceptorRegistrar的静态类型,在最核心的AbpKernelModule中会调用其Initialize()方法使得可以监听Ioc容器注册新类所触发的事件,是的,所注册的处理逻辑会判断Ioc新注册的类型或者其任意的方法是否应用了RequiresFeatureAttribute,如果有就会添加一个FeatureInterceptor的拦截器,在Target逻辑被执行之前,FeatureInterceptor会获取Target上RequiresFeatureAttribute中所指定必须处于开启状态的Feature集合(可以要求必须全部处于开启或任意一个开启),只有Feature Check Ok了,才会执行真正的逻辑,否则只会报异常。