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 ...
随机推荐
- 设计模式之Factory模式 代码初见
ObjectFactory就是通过Factory建造一个Object,比如说DBConnectionFactory就是专门建造DBConnection的工厂 BuilderFactory就是通过Fac ...
- You are what you write——沈向洋
title: You are what you write--沈向洋 date: 2018-02-21 13:18:28 tags: [随想,write] categories: 个人文章 --- A ...
- asyncio异步IO--协程(Coroutine)与任务(Task)详解
摘要:本文翻译自Coroutines and Tasks,主要介绍asyncio中用于处理协程和任务的方法和接口.在翻译过程中,译者在官方文档的基础上增加了部分样例代码和示意图表,以帮助读者对文档的理 ...
- 自动的自动化:EvoSuite 自动生成JUnit的测试用例
EvoSuite简介 EvoSuite是由Sheffield等大学联合开发的一种开源工具,用于自动生成测试用例集,生成的测试用例均符合Junit的标准,可直接在Junit中运行.得到了Google和Y ...
- 如何解决分配到Autoconfiguration IPV4 地址
配置完服务器静态IP后,在CMD窗口中查看ip地址,发现是Autoconfiguration IPV4. 上网搜索了,是关于虚拟服务器的,但是我没有配置虚拟服务器,有点奇怪. 使用下面的教程,可以解决 ...
- 基于 PHP 的数据爬取(QueryList)
基于PHP的数据爬取 官方网站站点 简单. 灵活.强大的PHP采集工具,让采集更简单一点. 简介: QueryList使用jQuery选择器来做采集,让你告别复杂的正则表达式:QueryList具有j ...
- LeetCode算法题-Next Greater Element I(Java实现)
这是悦乐书的第244次更新,第257篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第111题(顺位题号是496).你有两个数组(没有重复)nums1和nums2,其中nu ...
- 初步了解.net
一..net和C#是什么关系 .net是一个程序运行的平台,它是c#,vb,F#等程序运行的平台,为这些语言提供基础类库.公共语言运行时(CLR)等相关支持. C#是支持.net的一种编程语言..ne ...
- python import详解
1.import作用 引入模块 2.import的特点 一个程序中,import的模块不会重复被引用,如: # test1.py import test2 print test2.attr # tes ...
- 浅析foreach语句
本篇是我对于foreach语句(增强for)的总结: 我的总结流程如下: 1.先整体说明增强for遍历集合与数组之间的区别. 2.通过一维数组来说明(给出反编译的源码,形成对照). 3.通过二维数组来 ...