工作单元模式的实现
工作单元模式,简单的来讲就是把这次请求对数据库的操作以事务的形式提交,这里对数据库的操作可能包含多个聚合根的修改,或者多个Repository的修改. EFCore本身是实现了UOW,但是我们平时是怎么使用EFCore的,
1. 直接在上层,比如Controller里面 注入EFCore DBContex。单个Controller里面的操作支持事务。
2. 通过Repository 包一层,在Repository里面注入 EFCore DBContex,这个是常规做法。这样只能做到单个repository 里面的事务提交
我们实现工作单元的本质就是要把DBContex 作为单列来用,所有的repository里面的 savechanges 方法都需要注释掉,统一通过调用 DBContex 的savechanges 方法一次性保存到数据库。那么选择什么位置注入工作单元模式呢?
在同时能修改多个Repository的地方。那么在Domain里面可以吗?也可以,不够如果一个请求需要修改几个Domain呢?所以还是application层比较好。
由于DBContext 本身就是支持工作单元模式,那么有人会说直接在Application 层注入 DBContext 吗?调用所有的Domain后再调用 这个注入的DBContext 的savechanges 方法就可以了,没错,技术上是可以达到要求,但是感觉有点别扭,耦合依赖太强。
这个时候我们得把提炼一个工作单元的接口 接口里面定义save or commit之类的方法。然后在工作单元接口的实现类里面注入 EFCore DBContex, 再实现接口的save or conmmit方法里面调用 DBContex 的savechanges方法。 这样提供一个抽象也是有好处的,那天不想用EFCore 实现工作单元的时候也可以换,而不需要修改工作单元事务提交的代码。
说了这么多原理,说说实现方式,通过DI 容器 把DBContext 对象注册为 scope 生命周期(框架AddDbContext默认就是scope),同时把工作单元接口和实现也注册为scope。在application 层注入 工作单元接口,这样一次请求来在Application里修改完domain的领域对象后,调用工作单元的 save or commit方法统一事务提交数据库。

浙公网安备 33010602011771号