1. 程式人生 > >[Architect] Abp 框架原理解析(5) UnitOfWork

[Architect] Abp 框架原理解析(5) UnitOfWork

框架 方法 src options nalu res actions cnblogs 一個數

本節目錄

  • 介紹
  • 分析Abp源碼
  • 實現UOW

介紹

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為啟用事務.在本例中稍作擴展即可實現.

[Architect] Abp 框架原理解析(5) UnitOfWork