ABP框架 UnitOfWorkAttribute

记录下:

使用Castle.DynamicProxy实现动态代理

  参考项目地址:https://github.com/f135ta/SimpleProxy

  要点:

    方法上的 Attribute 与 对应的拦截器一一对应

    具体的Proxy由Castle.DynamicProxy实现

创建UnitOfWork

  1.由IUnitOfWorkManager在内部创建

 

 

   2. 创建 IUnitOfWork

  

   这里使用到了 _currentUnitOfWorkProvider 类来获取已存在的  IUnitOfWork。

    注意 “AsyncLocal” 用法 多线程共享变量,

    在异步情况下(async await) 等待之前的线程 与 等待之后的线程可能不是同一个线程。

  

  这个   ICurrentUnitOfWorkProvider 很关键

  设置Unitofwork值的,也将IUnitofwork变量内部 Outer 设置了。

  当该工作单元完成后,  ICurrentUnitOfWorkProvider.Current  的值就设置成了null,为下一个工作单元做准备。

仓储中的DbContext从何而来

  如图:

  

 

 

   再看下 IDbContextProvider 内部,这里以EF 为例。

  

 

 

   值是从当前的工作单元中创建,由

  

 

 

   ICurrentUnitOfWorkProvider 将 工作单元仓储 连接 。

  换句话说,工作单元 与 仓储操 操作的DbContext 是同一个。

外部工作单元从何而来IUnitOfWork.Outer

 

  看图,这是个类,类中有几个方法。

    

 

 

   由ioc容器创建该类,顺便注入了仓储与 工作单元管理器。

   在BeforeRun方法中手动创建了一个工作单元,using语句块中执行 _userRepository.Insert 方法时,会在 UnitOfWorkInterceptor 拦截器中执行(如下图) 创建工作单元

    

 

 

   在此时刻,由于手动创建的工作单元没执行 Complete()方法,那么 多线程共享变量(如下图AsyncLocalCurrentUnitOfWorkProvider继承ICurrentUnitOfWorkProvider 对Current的实现)

     ICurrentUnitOfWorkProvider.Current 值没设置为null。

  

 

   那么此时拦截器中创建的工作单元就 等于 手动创建的工作单元。

  如图:表示工作单元已存在

      

 

   

   

posted @ 2021-08-29 23:00  youliCC  阅读(193)  评论(0编辑  收藏  举报