知识全聚集 .Net Core 技术突破 | 简单说说工作单元
知识全聚集 .Net Core 技术突破 | 简单说说工作单元
教程
其他教程预览
分库分表项目实战教程
Git地址: https://github.com/MrChuJiu/EasyLogger
从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 技术突破 | 简单说说工作单元的更多相关文章
- 知识全聚集 .Net Core 技术突破 | 我用C#手把手教你玩微信自动化一
知识全聚集 .Net Core 技术突破 | 我用C#手把手教你玩微信自动化一 教程 01 | 模块化方案一 02 | 模块化方案二 03 | 简单说说工作单元 其他教程预览 分库分表项目实战教程 G ...
- 知识全聚集 .Net Core 技术突破 | 如何实现一个模块化方案一
简介 模块化的介绍一共2篇 这一篇我们实现一个功能非常简单的StartupModules模块化. 第二篇我们来实现一个ABP的模块化效果. 思考 其实来简单想一下模块化的实验思路,写个接口=>模 ...
- 知识全聚集 .Net Core 技术突破 丨ABP vNext 开始
介绍 很久没有更新博客了,之前想更新但是发现博客园崩了,外加工作上的调换也比较忙,最近有了点时间我来继续更新下这个系列的文章. 今年3月份我带着我们研发组同事,将公司产品从老Abp重构到Abp vNe ...
- 【HMS Core 6.0全球上线】Network Kit全链路网络加速技术,应用无惧网络拥塞
HMS Core 6.0已于7月15日全球上线,本次版本向广大开发者开放了众多全新能力与技术.其中HMS Core Network Kit开放了全链路网络加速技术,助力开发者为用户提供低时延的畅快网络 ...
- In-Cell、On-Cell和OGS全贴合屏幕技术区别
昨天刚发布的小米3用的是OGS全贴合屏幕技术,包括魅族MX3也是同样的技术,但是iPhone5是In-Cell屏幕技术,什么才是全贴合?它们之间到底有何区别?哪个好?小编今天就来普及一下全贴合屏幕技术 ...
- 单片机联网需求攀升 WIZnet全硬件TCP/IP技术崛起
--新华龙电子为韩国WIZnet公司网络芯片授权代理商,具有20多年的专业团队IC应用开发实力-- 如今不管是在企业还是小区.街道,甚至是居民室内,以太网接口无处不在.有鉴于此,电子设备必将向更加智能 ...
- Net Core平台灵活简单的日志记录框架NLog+SqlServer初体验
Net Core平台灵活简单的日志记录框架NLog+SqlServer初体验 前几天分享的"[Net Core平台灵活简单的日志记录框架NLog+Mysql组合初体验][http://www ...
- 基于Kubernetes 构建.NET Core技术中台
今天下午在腾讯云+社区社区分享了<基于Kubernetes 构建.NET Core技术中台>,下面是演讲内容的文字实录. 我们为什么需要中台 我们现在处于企业信息化的新时代.为什么这样说呢 ...
- ASP.NET Core 登录登出 - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core 登录登出 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 登录登出 上一章节我们总算完善了注册的功能,而且也添加了一个用户,现 ...
随机推荐
- k8s的namespace一直Terminating的完美解决方案
k8s的namespace一直Terminating的完美解决方案 在k8s集群中进行测试删除namespace是经常的事件,而为了方便操作,一般都是直接对整个名称空间进行删除操作. 相信道友们在进行 ...
- Java之格林威治时间格式转换成北京时间格式
Java之格林威治时间格式转换成北京时间格式 package com.mtons.mblog; import java.text.ParseException; import java.text.Si ...
- package.json文件配置说明
1.什么是package.json package.json文件是Node.js项目中的一个描述文件,执行npm init命令初始化项目后,在项目的根目录下自动生成该文件.package.json包含 ...
- 多测师讲解pthon_002字符,列表,元组,字段等
# # # 索引:# # # 正向索引: 0 1 2 3 4 5 6# # # l= a b c d e f g# # # 反向索引: -7 -6 -5 -4 ...
- MeteoInfoLab脚本示例:地图投影
在用axesm函数创建地图坐标系的时候可以指定地图投影(设置projinfo参数),地图投影可以通过projinfo函数来创建,里面的参数依据proj4投影字符串,可以参考此网页:http://rem ...
- Gradle的构建过程都不会?带你全面了解Android如何自定义Gradle 插件
目前 Android 工程的默认构建工具为 Gradle,我们在构建 APK 的时候往往会执行 ./gradlew assembleDebug 这样的命令.. 那么这个命令到底代表着什么含义呢?命令的 ...
- 什么是C和C++标准——小白必看
本文简要介绍编写C/C ++应用程序的领域,标准库的作用以及它是如何在各种操作系统中实现的. 我已经接触C++一段时间了,一开始就让我感到疑惑的是其内部结构:我所使用的内核函数和类从何而来? 谁发明了 ...
- swoole执行外部程序称为进程
<?php $child = new \Swoole\Process(function(\Swoole\Process $process){ $process->exec('/usr/lo ...
- S10 TES的八强赛,创造了奇迹,看看比赛时网友们怎么说的
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理 我相信很多观众会和我一样吧,当TES赢下第一局后开始心怀侥幸,赢下第二局后觉 ...
- 小C和小派的缠绵爱情——C语言调用Python代码
我妒忌你的开源,你眼红我的速度,不如我们就在一起吧! --------SJ2050 2019.4.9号更新:实现在未安装python环境的机子上运行调用了python程序的C语言代码! 文章目录 环境 ...