[Architect] Abp 框架原理解析(5) UnitOfWork
本节目录
介绍
UOW(全称UnitOfWork)是指工作单元.
在Abp中,工作单元对于仓储和应用服务方法默认开启。并在一次请求中,共享同一个工作单元.
同时在Abp中,不仅支持同一个数据库连接,还支持事务处理.
分析Abp源码
1.UnitOfWorkRegistrar
2.ComponentRegistered
3.IsConventionalUowClass
4.Intercept
5.PerformSyncUow
实现UOW
定义IUnitOfWork
1 2 3 4 5 6 7 8 9 10 11 12 | public interface IUnitOfWork { //1.开启事务 //2.设置Filter(本例中不做演示) void Begin(UnitOfWorkOptions options); void Complete(); } public class UnitOfWorkOptions { public bool ? IsTransactional { get ; set ; } } |
实现uow,在uow中会提供db的创建,这样才能管理到每个db.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | public class EfUnitOfWork : UnitOfWorkBase { public static DbContext DbContext { get ; set ; } public static DbContext GetDbContext() { if (DbContext == null ) { DbContext = new DemoDb(); } return DbContext; } public override void Begin(UnitOfWorkOptions options) { if (options.IsTransactional == true ) { CurrentTransaction = new TransactionScope(); } } public TransactionScope CurrentTransaction { get ; set ; } public override void Complete() { SaveChanges(); if (CurrentTransaction != null ) { CurrentTransaction.Complete(); } } private void SaveChanges() { DbContext.SaveChanges(); } } public abstract class UnitOfWorkBase : IUnitOfWork { public virtual void Begin(UnitOfWorkOptions options) { } public virtual void Complete() { } } |
定义与实现仓储层,这里不再做DbProvider.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public interface IRepository { } public interface ITaskRepository : IRepository { void Add(Task task); } public class TaskRepository : ITaskRepository { public void Add(Task task) { var db = (DemoDb)EfUnitOfWork.GetDbContext(); db.Tasks.Add(task); } } |
定义与实现应用层
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | public interface IApplicationService { } public interface ITaskAppService : IApplicationService { void CreateTask(CreateTaskInput input); } public class TaskAppService : ITaskAppService { private ITaskRepository _repository; public TaskAppService(ITaskRepository repository) { _repository = repository; } public void CreateTask(CreateTaskInput input) { _repository.Add( new Task(input.Name)); } } public class CreateTaskInput { public string Name { get ; set ; } } |
定义与实现uow拦截器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | internal class UnitOfWorkInterceptor : IInterceptor { private IUnitOfWork _unitOfWork; public UnitOfWorkInterceptor(IUnitOfWork unitOfWork) { _unitOfWork = unitOfWork; } public void Intercept(IInvocation invocation) { _unitOfWork.Begin( new UnitOfWorkOptions()); invocation.Proceed(); _unitOfWork.Complete(); } } |
定义在IApplicationService与IRepository接口下拦截
1 2 3 4 5 6 7 8 | static void Kernel_ComponentRegistered( string key, Castle.MicroKernel.IHandler handler) { var type = handler.ComponentModel.Implementation; if ( typeof (IApplicationService).IsAssignableFrom(type) || typeof (IRepository).IsAssignableFrom(type)) { handler.ComponentModel.Interceptors.Add( new InterceptorReference( typeof (UnitOfWorkInterceptor))); } } |
执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | static void Main( string [] args) { using ( var container = new WindsorContainer()) { container.Register(Component.For<IInterceptor, UnitOfWorkInterceptor>()); //先注入拦截器 container.Register(Component.For<IUnitOfWork, EfUnitOfWork>()); container.Kernel.ComponentRegistered += Kernel_ComponentRegistered; container.Register(Component.For<ITaskAppService, TaskAppService>()); container.Register(Component.For<ITaskRepository, TaskRepository>()); var person = container.Resolve<ITaskAppService>(); person.CreateTask( new CreateTaskInput() { Name = "3333" }); } Console.ReadKey(); } |
会自动在application method的结尾调用Complete.
另外也可以在uow上定义option为启用事务.在本例中稍作扩展即可实现.
本文地址:http://neverc.cnblogs.com/p/5263558.html
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 如果觉得还有帮助的话,可以点一下右下角的【推荐】,希望能够持续的为大家带来好的技术文章!想跟我一起进步么?那就【关注】我吧。
分类:
[15]Architect
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义