• 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。

      

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

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

          

       

       

    © 版权声明
    文章版权归作者所有,未经允许请勿转载。
  • 相关阅读:
    Go控制协裎并发数量的用法及实际中的一个案例
    使用Go处理带证书的请求(含发送POST请求的具体实现)
    利用递归的方式获取restful风格有nextUrl接口返回的数据
    使用Go解析HTTP返回数据为struct并存入数据库的操作
    Windows下安装Redis
    PHP自动加载composer下载的类库
    composer安装第三方类库
    Windows上composer安装
    ThinkPHP5分布式数据库读写分离
    MySQL主从同步及读写分离
  • 原文地址:https://www.cnblogs.com/youlicc/p/15204000.html
Copyright © 2020-2023  润新知