[Architect] Abp 框架原理解析(5) UnitOfWork
本节目录
介绍
UOW(全称UnitOfWork)是指工作单元.
在Abp中,工作单元对于仓储和应用服务方法默认开启。并在一次请求中,共享同一个工作单元.
同时在Abp中,不仅支持同一个数据库连接,还支持事务处理.
分析Abp源码
1.UnitOfWorkRegistrar
2.ComponentRegistered
3.IsConventionalUowClass
4.Intercept
5.PerformSyncUow
实现UOW
定义IUnitOfWork
public interface IUnitOfWork { //1.开启事务 //2.设置Filter(本例中不做演示) void Begin(UnitOfWorkOptions options); void Complete(); } public class UnitOfWorkOptions { public bool? IsTransactional { get; set; } }
实现uow,在uow中会提供db的创建,这样才能管理到每个db.
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.
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); } }
定义与实现应用层
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拦截器
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接口下拦截
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))); } }
执行
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
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 如果觉得还有帮助的话,可以点一下右下角的【推荐】,希望能够持续的为大家带来好的技术文章!想跟我一起进步么?那就【关注】我吧。