知识全聚集 .Net Core 技术突破 | 简单说说工作单元

教程

01 | 模块化方案一

02 | 模块化方案二

其他教程预览

分库分表项目实战教程

Git地址: https://github.com/MrChuJiu/EasyLogger

01 | 前言

02 | 简单的分库分表设计

03 | 控制反转搭配简单业务

04 | 强化设计方案

05 | 完善业务自动创建数据库

06 | 最终篇-通过AOP自动连接数据库-完成日志业务

从10.1到现在都太忙了,好久没更新文章了,也主要因为 工作单元这个东西我也是不知道该怎么才能讲明白,很多东西需要靠自己的一个理解。

今天可以稍微讲一下,看完这篇文章在对应源码去看,我觉得就会舒服很多。

本文章请一定要配合源码食用,注释都在源码里写好了。

https://github.com/MrChuJiu/Easy.Core.Flow

简单说说运行路线

工作单元的开始入口是从 AspNetCoreUowMiddleware 中间件开始的

1.判断是否匹配到了路由地址
2.判断是否携带 UnitOfWorkAttribute 属性 如果携带了获取属性值
3.判断是否携带了属性中禁用工作单元,如果是直接跳出该中间件
4.获取链接字符串名称 启动一个工作单元包裹当前中间件
5.接口操作结束后 判断相应状态提交工作单元

先看主要的文件和描述

接口文件 描述 实现
IUnitOfWork 工作单元实例 UnitOfWorkBase
ICurrentUnitOfWorkProvider 工作单元提供者 AsyncLocalCurrentUnitOfWorkProvider
IUnitOfWorkManager 工作单元管理器 DefaultUnitOfWorkManager

一个基础的EF工作单元操作(记住这个概念我们接下来看代码)

var unitOfWorkManager = scopeServiceProvider.GetService<IUnitOfWorkManager>();
using (var uow = unitOfWorkManager.Begin())
{
var appContext = unitOfWorkManager.Current.GetDbContext<AppDbContext>();
var user = new User();
user.Creator = "Creator";
appContext.Users.Add(user);
await uow.CompleteAsync();
}
表面通过 工作单元管理器创建一个工作单元实例 IUnitOfWork 实例
内部: 工作单元管理器中 将 工作单元配置参数(事务级别/事务范围/超时/事件/连接字符串显示名称) 存放到工作单元提供者后续 提供给具体实现进行使用

IUnitOfWorkManager 工作单元管理器



Begin() 方法返回的是一个类型为 IUnitOfWorkCompleteHandle 工作单元事件处理器 主要看继承他的方法

一:InnerUnitOfWorkCompleteHandle

主要调用 Complete()/CompleteAsync() 会将 _isCompleteCalled 置为 true,然后在 Dispose() 方法内会进行检测,为 faslse 的话直接抛出异常。

可以看到在 InnerUnitOfWorkCompleteHandle 内部并不会真正地调用 DbContext.SaveChanges() 进行数据保存。

该类可以在 Begin() 方法中看到在创建 UOW 对象的时候,他在内部进行了一个判断,如果不存在外部工作单元的情况下才会创建 InnerUnitOfWorkCompleteHandle 对象,否则是解析的一个 IUnitOfWork 对象。

请下载代码调试

      using (var scope = app.ApplicationServices.CreateScope())
{ var scopeServiceProvider = scope.ServiceProvider; var unitOfWorkManager = scopeServiceProvider.GetService<IUnitOfWorkManager>(); using (var outerUOW1 = unitOfWorkManager.Begin()) // 这里返回的是 IOC 解析出的 IUnitOfWork
{
var appContext1 = unitOfWorkManager.Current.GetDbContext<AppDbContext>(); var user1 = new User();
user1.Creator = "Creator1111";
appContext1.Users.Add(user1);
using (var innerUOW2 = unitOfWorkManager.Begin()) // 内部 UOW
{
var appContext2 = unitOfWorkManager.Current.GetDbContext<AppDbContext>();
var user2 = new User();
user2.Creator = "Creator222";
appContext2.Users.Add(user2); using (var innerUOW3 = unitOfWorkManager.Begin()) // 内部 UOW
{
var appContext3 = unitOfWorkManager.Current.GetDbContext<AppDbContext>(); var user3 = new User();
user3.Creator = "Creator333";
appContext3.Users.Add(user3);
await innerUOW3.CompleteAsync();
}
await innerUOW2.CompleteAsync();
}
await outerUOW1.CompleteAsync();
}
}

二:IUnitOfWork

Id 是使用的 Guid 生成的,用于标识每个工作单元。

Outer 则是当前 UOW 对象的引用对象

Begin 根据工作单元选项创建(各个ORM启动工作单元的方式不同,让他们各自去继承实现)

EfCoreUnitOfWork -> UnitOfWorkBase -> IUnitOfWork

ICurrentUnitOfWorkProvider 工作单元提供者

我们在 UnitOfWorkManager.Begin() 方法最后一行 _currentUnitOfWorkProvider.Current = uow;

_currentUnitOfWorkProvider 的实现在 AsyncLocalCurrentUnitOfWorkProvider 内部,其作用是维护一个 UOW 链 确保当前的工作单元始终是最新的

重点是 value.Outer = AsyncLocalUow.Value.UnitOfWork; = IUnitOfWork.Outer

电脑截图有限最好下载代码去对着文章自己过一下

EfCoreUnitOfWork 落实到EFCore实际处理

EfCoreUnitOfWork -> UnitOfWorkBase -> IUnitOfWork

随随便便结尾

IUnitOfWork、ICurrentUnitOfWorkProvider、IUnitOfWorkManager 实现原理

EfCoreUnitOfWork 具体的实现

其它类具体的解释我都写了注释,自己下载看吧,

鸣谢

玩双截棍的熊猫

源地址:https://github.com/rivenfx/Framework

我只能说:ABP牛皮!!!

知识全聚集 .Net Core 技术突破 | 简单说说工作单元的更多相关文章

  1. 知识全聚集 .Net Core 技术突破 | 我用C#手把手教你玩微信自动化一

    知识全聚集 .Net Core 技术突破 | 我用C#手把手教你玩微信自动化一 教程 01 | 模块化方案一 02 | 模块化方案二 03 | 简单说说工作单元 其他教程预览 分库分表项目实战教程 G ...

  2. 知识全聚集 .Net Core 技术突破 | 如何实现一个模块化方案一

    简介 模块化的介绍一共2篇 这一篇我们实现一个功能非常简单的StartupModules模块化. 第二篇我们来实现一个ABP的模块化效果. 思考 其实来简单想一下模块化的实验思路,写个接口=>模 ...

  3. 知识全聚集 .Net Core 技术突破 丨ABP vNext 开始

    介绍 很久没有更新博客了,之前想更新但是发现博客园崩了,外加工作上的调换也比较忙,最近有了点时间我来继续更新下这个系列的文章. 今年3月份我带着我们研发组同事,将公司产品从老Abp重构到Abp vNe ...

  4. 【HMS Core 6.0全球上线】Network Kit全链路网络加速技术,应用无惧网络拥塞

    HMS Core 6.0已于7月15日全球上线,本次版本向广大开发者开放了众多全新能力与技术.其中HMS Core Network Kit开放了全链路网络加速技术,助力开发者为用户提供低时延的畅快网络 ...

  5. In-Cell、On-Cell和OGS全贴合屏幕技术区别

    昨天刚发布的小米3用的是OGS全贴合屏幕技术,包括魅族MX3也是同样的技术,但是iPhone5是In-Cell屏幕技术,什么才是全贴合?它们之间到底有何区别?哪个好?小编今天就来普及一下全贴合屏幕技术 ...

  6. 单片机联网需求攀升 WIZnet全硬件TCP/IP技术崛起

    --新华龙电子为韩国WIZnet公司网络芯片授权代理商,具有20多年的专业团队IC应用开发实力-- 如今不管是在企业还是小区.街道,甚至是居民室内,以太网接口无处不在.有鉴于此,电子设备必将向更加智能 ...

  7. Net Core平台灵活简单的日志记录框架NLog+SqlServer初体验

    Net Core平台灵活简单的日志记录框架NLog+SqlServer初体验 前几天分享的"[Net Core平台灵活简单的日志记录框架NLog+Mysql组合初体验][http://www ...

  8. 基于Kubernetes 构建.NET Core技术中台

    今天下午在腾讯云+社区社区分享了<基于Kubernetes 构建.NET Core技术中台>,下面是演讲内容的文字实录. 我们为什么需要中台 我们现在处于企业信息化的新时代.为什么这样说呢 ...

  9. ASP.NET Core 登录登出 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 登录登出 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 登录登出 上一章节我们总算完善了注册的功能,而且也添加了一个用户,现 ...

随机推荐

  1. Jmeter5.3源码编译

    下载源码 https://jmeter.apache.org/download_jmeter.cgi 配置网络环境(重要) 下载 Proxifier 配置上网条件 导入Idea 通过 Idea 的 O ...

  2. Ubuntu通过Nginx安装Webdav

    使用KeePass保存密码,在个人服务器上安装WebDav协议. # nginx nginx-extras apache2-utils sudo aptitude install nginx ngin ...

  3. Java NIO:通道

    最近打算把Java网络编程相关的知识深入一下(IO.NIO.Socket编程.Netty) Java NIO主要需要理解缓冲区.通道.选择器三个核心概念,作为对Java I/O的补充, 以提升大批量数 ...

  4. dockerfile镜像设置中文

    一.dockerfile镜像设置中文 centos镜像默认不支持中文,把下面的内容加到dockerfile即可 # 修改时区 RUN rm -rf /etc/localtime && ...

  5. MeteoInfoLab脚本示例:AIRS Swath HDF数据

    例子中的AIRS Swath HDF数据在Polar Stereographic(南极)投影中接近矩形,需要先从数据中读出经纬度及相关数据数组,利用surfacem函数绘制Swath数据(散点),在s ...

  6. Pythonic【15个代码示例】

    Python由于语言的简洁性,让我们以人类思考的方式来写代码,新手更容易上手,老鸟更爱不释手. 要写出 Pythonic(优雅的.地道的.整洁的)代码,还要平时多观察那些大牛代码,Github 上有很 ...

  7. xuexi

    1.内存的编址方法就是内存地址与内存单元格一一对应且永久绑定.计算机的cpu只认识内存地址,不关心内存单元格的位置和内容.通过硬件的设计来达到通过内存地址找到内存单元格. 2.内存的编址是以字节为单位 ...

  8. go正则

    package main import ( "fmt" "regexp" ) func main() { context1 := "3.14 1231 ...

  9. post 和php://input 转

    $_POST['paramName'] 获取通过表单(multipart/form-data)提交的数据.但有时客户端会直接将请求数据以字符串的形式都放到 body 里传递过来,那么服务端就需要使用  ...

  10. centos8使用systemctl管理运行级别

    一,什么是systemd的target? 1,关于systemd/systemctl的相关知识,请移步到这一篇 https://www.cnblogs.com/architectforest/p/12 ...