zoukankan      html  css  js  c++  java
  • [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为启用事务.在本例中稍作扩展即可实现.

  • 相关阅读:
    开源项目中标准文件命名和实践
    linux远程拷贝命令-scp
    Linux访问Windows共享目录的方法——smbclient
    ADB Fix error : insufficient permissions for device
    APT典型应用示例
    我的参考书籍列表
    GCC Reference
    GNU make简介
    Windows下搭建Android NDK开发环境及命令行编译
    Git命令行基本操作
  • 原文地址:https://www.cnblogs.com/zhaodahai/p/6824063.html
Copyright © 2011-2022 走看看