千家信息网

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

发表于:2024-11-14 作者:千家信息网编辑
千家信息网最后更新 2024年11月14日,本节目录介绍分析Abp源码实现UOW介绍UOW(全称UnitOfWork)是指工作单元.在Abp中,工作单元对于仓储和应用服务方法默认开启。并在一次请求中,共享同一个工作单元.同时在Abp中,不仅支持
千家信息网最后更新 2024年11月14日[Architect] Abp 框架原理解析(5) UnitOfWork

本节目录

  • 介绍

  • 分析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());//先注入拦截器

container.Register(Component.For());

container.Kernel.ComponentRegistered += Kernel_ComponentRegistered;

container.Register(Component.For());

container.Register(Component.For());

var person = container.Resolve();

person.CreateTask(new CreateTaskInput() { Name = "3333" });

}

Console.ReadKey();

}

会自动在application method的结尾调用Complete.

另外也可以在uow上定义option为启用事务.在本例中稍作扩展即可实现.


0