HTML5技术

ABP使用及框架解析系列 - [Unit of Work part.2-框架实现] - An.Cup.Of.Coffee

字号+ 作者:H5之家 来源:H5之家 2015-10-31 12:01 我要评论( )

前言ABP ABP是ASP.NET Boilerplate Project的简称。 ABP的官方网站: ABP在Github上的开源项目:https://github.com/aspnetboilerplate ABP其他学习博客推荐及介绍: ABP中Unit of Work概念及使用 如果这是你首次接触ABP框架或ABP的Unit of Work,推荐先看看

前言 ABP

ABP是“ASP.NET Boilerplate Project”的简称。

ABP的官方网站:

ABP在Github上的开源项目:https://github.com/aspnetboilerplate

ABP其他学习博客推荐及介绍:

 

ABP中Unit of Work概念及使用

如果这是你首次接触ABP框架或ABP的Unit of Work,推荐先看看 ABP使用及框架解析系列-[Unit of Work part.1-概念及使用]

 

框架实现 温馨提示

1.ABP的Unit of Work相关代码路径为:/Abp/Domain/Uow

2.框架实现中,代码不会贴全部的,但是会说明代码在项目中的位置,并且为了更加直观和缩短篇幅,对代码更细致的注释,直接在代码中,不要忘记看代码注释哈,。

3.博客中的代码,有一些方法是可以点击的!

 

动态代理/拦截器/AOP

上面讲到Unit of Work有两个默认实现,领域服务和仓储库的每个方法默认就是一个工作单元,这个是如何实现的呢?在方法上添加一个UnitOfWork特性也就让该方法为一个工作单元,这又是如何实现的呢?上面的标题已然暴露了答案——动态代理

在ABP中,使用了Castle的DynamicProxy进行动态代理,在组件注册是进行拦截器的注入,具体代码如下:

UnitOfWorkRegistrar { Initialize(IIocManager iocManager) {//该方法会在应用程序启动的时候调用,进行事件注册 iocManager.IocContainer.Kernel.ComponentRegistered += ComponentRegistered; } ComponentRegistered(string key, IHandler handler) { if (UnitOfWorkHelper.(handler.ComponentModel.Implementation)) {//判断类型是否实现了IRepository或IApplicationService,如果是,则为该类型注册拦截器(UnitOfWorkInterceptor) handler.ComponentModel.Interceptors.Add(new InterceptorReference(typeof(UnitOfWorkInterceptor))); } else if (handler.ComponentModel.Implementation.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Any(UnitOfWorkHelper.)) {//或者类型中任何一个方法上应用了UnitOfWorkAttribute,同样为类型注册拦截器(UnitOfWorkInterceptor) handler.ComponentModel.Interceptors.Add(new InterceptorReference(typeof(UnitOfWorkInterceptor))); } } }

IsConventionalUowClass(Type type) { return typeof(IRepository).IsAssignableFrom(type) || typeof(IApplicationService).IsAssignableFrom(type); }

HasUnitOfWorkAttribute(MemberInfo methodInfo) { return methodInfo.IsDefined(typeof(UnitOfWorkAttribute), true); }

拦截器UnitOfWorkInterceptor实现了IInterceptor接口,在调用注册了拦截器的类的方法时,会被拦截下来,而去执行IInterceptor的Intercept方法,下面是Intercept方法的代码实现:

public void Intercept(IInvocation invocation) { if (_unitOfWorkManager.Current != null) {//如果当前已经在工作单元中,则直接执行被拦截类的方法 invocation.Proceed(); return; } unitOfWorkAttr = UnitOfWorkAttribute.(invocation.MethodInvocationTarget); if (unitOfWorkAttr == null || unitOfWorkAttr.IsDisabled) {//如果当前方法上没有UnitOfWorkAttribute或者是设置为Disabled,则直接调用被拦截类的方法 invocation.Proceed(); return; } //走到这里就表示是需要将这个方法作为工作单元了,详情点击查看 (invocation, unitOfWorkAttr.CreateOptions()); }

internal static UnitOfWorkAttribute GetUnitOfWorkAttributeOrNull(MemberInfo methodInfo) { attrs = methodInfo.GetCustomAttributes(typeof(UnitOfWorkAttribute), false); if (attrs.Length > 0) { return (UnitOfWorkAttribute)attrs[0]; } if (UnitOfWorkHelper.IsConventionalUowClass(methodInfo.DeclaringType)) { UnitOfWorkAttribute(); } return null; }

private void PerformUow(IInvocation invocation, UnitOfWorkOptions options) { if (AsyncHelper.IsAsyncMethod(invocation.Method)) {//被拦截的方法为异步方法 (invocation, options); } else {//被拦截的方法为同步方法 (invocation, options); } }

private void PerformSyncUow(IInvocation invocation, UnitOfWorkOptions options) { (var uow = _unitOfWorkManager.Begin(options)) { invocation.Proceed(); uow.Complete(); } }

private void PerformAsyncUow(IInvocation invocation, UnitOfWorkOptions options) { uow = _unitOfWorkManager.Begin(options); invocation.Proceed(); if (invocation.Method.ReturnType == typeof(Task)) {//如果是无返回值的异步任务 invocation.ReturnValue = InternalAsyncHelper.( (Task)invocation.ReturnValue, async () => await uow.CompleteAsync(), exception => uow.Dispose() ); } {//如果是有返回值的异步任务 invocation.ReturnValue = InternalAsyncHelper.( invocation.Method.ReturnType.GenericTypeArguments[0], invocation.ReturnValue, async () => await uow.CompleteAsync(), (exception) => uow.Dispose() ); } }

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • Dora.Interception: 一个为.NET Core度身定制的AOP框架 - Artech

    Dora.Interception: 一个为.NET Core度身定制的AOP框架 - Artech

    2017-05-02 11:00

  • 【Vue 入门】使用 Vue2 开发一个展示项目列表的应用 - zhangjk

    【Vue 入门】使用 Vue2 开发一个展示项目列表的应用 - zhangjk

    2017-04-30 16:00

  • 对于Bootstrap的介绍以及如何使用 - novai-L

    对于Bootstrap的介绍以及如何使用 - novai-L

    2017-04-29 09:00

  • 在Delphi下使用迅雷APlayer组件进行免注册开发 - Delphi力量

    在Delphi下使用迅雷APlayer组件进行免注册开发 - Delphi力量

    2017-04-28 15:00

网友点评
p