ABP中的拦截器之EntityHistoryInterceptor
今天我们接着之前的系列接着来写另外一种拦截器EntityHistoryInterceptor,这个拦截器到底是做什么的呢?这个从字面上理解是实体历史?这个到底是什么意思?带着这个问题我们来一步步去分析。
整个拦截器的运行过程和前面几篇是一样的,这里就不再赘述,首先也是在AbpBootstrapper的构造函数中完成初始化过程。
private void AddInterceptorRegistrars()
{
ValidationInterceptorRegistrar.Initialize(IocManager);
AuditingInterceptorRegistrar.Initialize(IocManager);
EntityHistoryInterceptorRegistrar.Initialize(IocManager);
UnitOfWorkRegistrar.Initialize(IocManager);
AuthorizationInterceptorRegistrar.Initialize(IocManager);
}
首先我们来从这个Initialize方法来进行说明,然后再来一步步分析。
internal static class EntityHistoryInterceptorRegistrar
{
public static void Initialize(IIocManager iocManager)
{
iocManager.IocContainer.Kernel.ComponentRegistered += (key, handler) =>
{
if (!iocManager.IsRegistered<IEntityHistoryConfiguration>())
{
return;
} var entityHistoryConfiguration = iocManager.Resolve<IEntityHistoryConfiguration>(); if (ShouldIntercept(entityHistoryConfiguration, handler.ComponentModel.Implementation))
{
handler.ComponentModel.Interceptors.Add(new InterceptorReference(typeof(EntityHistoryInterceptor)));
}
};
} private static bool ShouldIntercept(IEntityHistoryConfiguration entityHistoryConfiguration, Type type)
{
if (type.GetTypeInfo().IsDefined(typeof(UseCaseAttribute), true))
{
return true;
} if (type.GetMethods().Any(m => m.IsDefined(typeof(UseCaseAttribute), true)))
{
return true;
} return false;
}
}
这个还是和之前一样去订阅IOC容器中的IocContainer.Kernel.ComponentRegistered这个事件,然后在整个ABP框架运行并将每一个接口对应的类型注册到IOC容器的视乎会调用上面订阅的方法。然后在订阅方法中首先判断IOC容器中是否注册过IEntityHistoryConfiguration这个接口,如果没有注册过那么就直接返回了?那么ABP框架到底有没有注册过这个接口呢?
这个在ABP中的AbpBootstrapper的Initialize方法中就完成了注册,具体的过程就不再描述,重点的是下面这句代码。
Component.For<IEntityHistoryConfiguration, EntityHistoryConfiguration>().ImplementedBy<EntityHistoryConfiguration>().LifestyleSingleton()
这个在ABP系统中注册了唯一的一个单例实现EntityHistoryConfiguration这个类,我们来看看这个类的实现。
internal class EntityHistoryConfiguration : IEntityHistoryConfiguration
{
public bool IsEnabled { get; set; } public bool IsEnabledForAnonymousUsers { get; set; } public IEntityHistorySelectorList Selectors { get; } public List<Type> IgnoredTypes { get; } public EntityHistoryConfiguration()
{
IsEnabled = true;
Selectors = new EntityHistorySelectorList();
IgnoredTypes = new List<Type>()
{
typeof(EntityChangeSet),
typeof(EntityChange),
typeof(EntityPropertyChange)
};
}
}
我们先不分析这个类到底为了配置些什么,我们接着看EntityHistoryInterceptorRegistrar这个类,在这个类中是否启用拦截,就看当前类型Type中是否定义了自定义属性 UseCaseAttribute,这个属性可以在类上面,也可以定义在类里面的方法中,如果这些类型或者类型里面的方法定义了这个自定义属性,那么就启动后面的拦截过程了,这里面这些类通常是定义在应用层或领域层中的具体和业务相关的类。在判断了这些之后就是添加我们的EntityHistoryInterceptor拦截器了。
下面我们就来重点分析EntityHistoryInterceptor这个拦截器了。
internal class EntityHistoryInterceptor : IInterceptor
{
public IEntityChangeSetReasonProvider ReasonProvider { get; set; } public EntityHistoryInterceptor()
{
ReasonProvider = NullEntityChangeSetReasonProvider.Instance;
} public void Intercept(IInvocation invocation)
{
var methodInfo = invocation.MethodInvocationTarget;
var useCaseAttribute = methodInfo.GetCustomAttributes(true).OfType<UseCaseAttribute>().FirstOrDefault()
?? methodInfo.DeclaringType.GetCustomAttributes(true).OfType<UseCaseAttribute>().FirstOrDefault(); if (useCaseAttribute?.Description == null)
{
invocation.Proceed();
return;
} using (ReasonProvider.Use(useCaseAttribute.Description))
{
invocation.Proceed();
}
}
}
在这个拦截器中,如果一个已拦截的方法在执行前首先会执行Intercept这个方法,在这个方法中我们会往其中的字段Description中添加描述,然后会执行ReasonProvider.Use这个方法,然后将之前的描述Description作为参数进行传递。
ABP中的拦截器之EntityHistoryInterceptor的更多相关文章
- ABP中的拦截器之ValidationInterceptor(上)
从今天这一节起就要深入到ABP中的每一个重要的知识点来一步步进行分析,在进行介绍ABP中的拦截器之前我们先要有个概念,到底什么是拦截器,在介绍这些之前,我们必须要了解AOP编程思想,这个一般翻译是面向 ...
- ABP中的拦截器之AuditingInterceptor
在上面两篇介绍了ABP中的ValidationInterceptor之后,我们今天来看看ABP中定义的另外一种Interceptor即为AuditingInterceptor,顾名思义就是一种审计相关 ...
- ABP中的拦截器之ValidationInterceptor(下)
在上篇我分析了整个ABP中ValitationInterceptor的整个过程,就其中涉及到的Validator过程没有详细的论述,这篇文章就这个过程进行详细的论述,另外任何一个重要的特性如何应用是最 ...
- 6. abp中的拦截器
abp拦截器基本定义 拦截器接口定义: public interface IAbpInterceptor { void Intercept(IAbpMethodInvocation invocatio ...
- ABP拦截器之UnitOfWorkRegistrar(一)
ABP中UnitOfWorkRegistrar拦截器是整个ABP中非常关键的一个部分,这个部分在整个业务系统中也是用的最多的一个部分,这篇文章的主要思路并不是写如何使用ABP中的UnitOfWork, ...
- ABP拦截器之AuthorizationInterceptor
在整体介绍这个部分之前,如果对ABP中的权限控制还没有一个很明确的认知,请先阅读这篇文章,然后在读下面的内容. AuthorizationInterceptor看这个名字我们就知道这个拦截器拦截用户一 ...
- ABP拦截器之UnitOfWorkRegistrar(二)
在上面一篇中我们主要是了解了在ABP系统中是如何使用UnitOfWork以及整个ABP系统中如何执行这些过程的,那么这一篇就让我们来看看UnitOfWorkManager中在执行Begin和Compl ...
- ABP源码分析三十五:ABP中动态WebAPI原理解析
动态WebAPI应该算是ABP中最Magic的功能之一了吧.开发人员无须定义继承自ApiController的类,只须重用Application Service中的类就可以对外提供WebAPI的功能, ...
- (实用篇)浅谈PHP拦截器之__set()与__get()的理解与使用方法
"一般来说,总是把类的属性定义为private,这更符合现实的逻辑. 但是,对属性的读取和赋值操作是非常频繁的,因此在PHP5中,预定义了两个函数"__get()"和&q ...
随机推荐
- mock测试
看到群里有人说mock测试,究竟什么是mock测试呢?开始自己也没明白,查了下相关资料.还是很有必要了解哈:那么mock测试能解决什么问题?mock测试要如何做呢?今天为大家做简单介绍.mock测试就 ...
- 微信小程序picker的坑
js文件: Companyarr: [{ id: '公司id1', companyname: "公司1的名字" }, { id: '公司id2', companyname: &qu ...
- H5页面的高度宽度100%
解决方案1: 设置如下:html,body{ min-height:100vh; background-color:#fff; }这样高度首先不会写死,而且满足最小高度是满屏 解决方案2: 可以用vh ...
- vue中的路由的跳转的参数
vue中的路由跳转传参 params 与 query this.$router.push({ name:"detail", params:{ name:'nameValue', c ...
- 异步加载js的三种方法
js加载时间线 : 它是根据js出生的那一刻开始记录的一系列浏览器按照顺序做的事,形容的就是加载顺序,可以用来优化什么东西,理论基础,背下来. 1.创建Document对象,开始解析web页面.解析H ...
- Sql server 2014 数据库还原奇异现象
用A库来还原B库 对正在使用的B库执行还原,还原时修改数据库名称,还原出错,提示数据库正在使用.删除B库,仍然提示正在使用,感觉像僵尸 重启SQL SERVER,因B库已删除,在A库上点击 ...
- input file实现多选和限制文件上传类型
<!-- input file accept 属性设置可上传文件的类型 multiple属性设置可多文件上传--> <!-- accept 并未真正的实现限制上传文件类型,只是在 ...
- Asp.Net Core 全局模型验证
public class ActionFilter : IActionFilter { /// <summary> /// action 执行之前 /// </summary> ...
- Ubuntu 下重启网络的方法
命令是: sudo /etc/init.d/networking restart 但是可能会遇到下面的提示: Running /etc/init.d/networking restart is dep ...
- 监控glusterfs
监控集群状态 [4ajr@elk1 scripts]$ cat glusterfs_peer_status.sh #!/bin/bash peer_status=`sudo gluster peer ...