[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 { getset; }

}

实现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 { getset; }

    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 { getset; }

    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 { getset; }

}

定义与实现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为启用事务.在本例中稍作扩展即可实现.

时间: 2024-10-22 13:35:33

[Architect] Abp 框架原理解析(5) UnitOfWork的相关文章

EventBus框架原理解析(结合源码)(下)

上一篇文章EventBus框架原理解析(结合源码)(上),给大家讲述了EventBus中实体类的封装和register()的具体代码. 接下来我们看另外一个重要方法post(),这个方法显然是要根据传入的参数类型,从subscriptionsByEventType取出对应的subscription /** Posts the given event to the event bus. */ public void post(Object event) {//event就是参数 PostingTh

[Architect] ABP(现代ASP.NET样板开发框架)(7) 依赖注入

本节目录: 什么是依赖 传统方式的问题 解决方案 构造函数注入 属性注入 注入框架 Abp依赖注入框架 注册 通常注册 帮助接口 自定义注册 解析 构造函数 & 属性注入 IIocResolver & IIocManager 扩展 IShouldInitialize ASP.NET MVC & ASP.NET Web API注入 什么是依赖 如果你已经知道依赖注入思想,构造函数和属性注入模式,你可以跳到下节. 维基:"依赖注入是1种软件设计模式,在这种模式下,1个或多个依

[Architect] ABP(现代ASP.NET样板开发框架)(9) Caching

本节目录 介绍 ICacheManager WARNING: GetCache Method ICache ITypedCache Configuration 介绍 Abp提供了1个缓存的抽象.内部使用这个缓存抽象.虽然默认的实现使用MemoryCache,但是可以切换成其他的缓存. ICacheManager 提供缓存的接口为ICacheManager.我们可以注入并使用他.如: public class TestAppService : ApplicationService { privat

[Architect] ABP(现代ASP.NET样板开发框架)(2) 分层架构

本节目录 介绍 Domain Layer Application Layer Infrastructure Layer Web Layer SPA & MPA frameworks/libraries 其他 介绍 为了减少复杂性和提高代码的可重用性,采用分层架构是一种被广泛接受的技术. ABP遵循Domain Driven Design,在DDD中,会有4个基础分层. Presentation(展现层): 引用 Application Layer ,提供用户界面. Application(应用层

[Architect] ABP(现代ASP.NET样板开发框架)(1) 介绍

本节目录: 简介 代码示例 支持的功能 GitHub 简介 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ABP不仅仅是1个框架,更提供了一个基于DDD和最佳实践方案 ABP的官方网站:http://www.aspnetboilerplate.com ABP在Github上的开源项目:https://github.com/aspnetboilerplate 代码示例 (Application层代码示例) public class Task

Android 图片三级缓存加载框架原理解析与代码实现

本文主要介绍三级缓存的原理解析与实现方式.以前一直觉得三级缓存图片加载是一个很难理解的东西,但是自己看了一下午再试着写了一遍之后感觉还是只要沉下心思考还时很容易熟悉掌握的. 所谓三级缓存:首先是内存-文件(外存)-网络三级缓存机制. 首先: 框架需要一个接入方法NGImageloadHelper.java: /** * 图片加载框架使用帮助类 * Created by nangua on 2016/7/8. */ public class NGImageloadHelper { /** * 处理

ABP架构解析

ABP总体介绍 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应用程序的新起点,它旨在成为一个通用的WEB应用程序框架和项目模板. ASP.NET Boilerplate 基于DDD的经典分层架构思想,实现了众多DDD的概念(但没有实现所有DDD的概念). ABP的官方网站:http://www.aspnetboilerplate.com ABP在Github上

Linux TC(Traffic Control)框架原理解析

近日的工作多多少少和Linux的流控有点关系,自打几年前知道有TC这么一个玩意儿并且多多少少理解了它的原理之后,我就没有再动过它,因为我不喜欢TC命令行,实在是太繁琐了,iptables命令行也比较繁琐,但是比TC命令行直观,而TC命令行则太过于技术化.也许是我对TC框架没有对Netfilter框架理解深刻吧,也许是的.iptables/Netfilter对应的就是tc/TC.       Linux内核内置了一个Traffic Control框架,可以实现流量限速,流量整形,策略应用(丢弃,N

EventBus框架原理解析(结合源码)(上)

上一篇文章http://blog.csdn.net/crazy__chen/article/details/47425779 和大家一起模仿EventBus的实现机制,和大家一起写出了一个简易的EventBus.通过这个项目,大家应该对EventBus的实现机理由大致的了解. 建议大家在看这篇文章之前,先读上一篇文章,有助于了解. 本篇文章希望通过对Github上EventBus的源码,向大家讲些其实现细节. 网上有很多讲EventBus架构的文章,我看了以后都觉得不大清晰,希望这篇文章可以帮到