Lind.DDD.UoW工作单元的实现

简介:

工作单元UoW我们几乎在任务一个像样的框架里都可以找到它的足迹,是的,对于大型系统来说,他是很重要的,保持数据一致性,维持事务状态这都是它要为系统实现的功能,而在不同的框架里,实现UoW的机制也是不同的,在Lind.DDD中,采用了一种共同注册,统一提交的方式来实现UoW!

UoW结构图

我们来看一下大叔工作单元的代码实现,首先看一下IUnitOfWorkRepository,我们的仓储接口会实现它,以便之后我们的仓储对象可以添加到工作单元里

    /// <summary>
    /// 工作单元中仓储接口CRUD操作
    /// 需要使用工作单元的仓储,需要实现本接口(IRepository,IExtensionRepository)
    /// </summary>
    public interface IUnitOfWorkRepository
    {
        /// <summary>
        /// 添加实体
        /// </summary>
        /// <param name="item"></param>
        void UoWInsert(IEntity item);
        /// <summary>
        /// 更新实体
        /// </summary>
        /// <param name="item"></param>
        void UoWUpdate(IEntity item);
        /// <summary>
        /// 移除实体
        /// </summary>
        /// <param name="item"></param>
        void UoWDelete(IEntity item);
    }

接下来,我们再来说一下IUnitOfWork接口,它是工作单元入口的接口,有添加到单元和提交单元两个方法,使用简单明了,内部有字典对象,用来存储要提交的操作,这也是工作单元的核心,IEntity是实体的标识接口,所有实体都要继承它,而IUnitOfWorkRepository是仓储的标识接口,所以仓储接口都要继承它。

   /// <summary>
    /// 工作单元
    /// 所有数据上下文对象都应该继承它,面向仓储的上下文应该与具体实现(存储介质,ORM)无关
    /// </summary>
    public interface IUnitOfWork
    {
        /// <summary>
        /// 向工作单元中注册变更
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="type"></param>
        /// <param name="repository"></param>
        void RegisterChangeded(IEntity entity, SqlType type, IUnitOfWorkRepository repository);
        /// <summary>
        /// 向数据库提交变更
        /// </summary>
        void Commit();
    }

我们来看一下,大叔是如何实现IUnitOfWork接口的吧

   /// <summary>
    /// 工作单元,主要用于管理事务性操作
    /// Author:Lind.zhang
    /// </summary>
    public class UnitOfWork : IUnitOfWork
    {
        #region Fields
        /// <summary>
        /// 操作行为字典
        /// </summary>
        private IDictionary<IEntity, IUnitOfWorkRepository> insertEntities;
        private IDictionary<IEntity, IUnitOfWorkRepository> updateEntities;
        private IDictionary<IEntity, IUnitOfWorkRepository> deleteEntities;

        #endregion

        #region Constructor

        public UnitOfWork()
        {
            insertEntities = new Dictionary<IEntity, IUnitOfWorkRepository>();
            updateEntities = new Dictionary<IEntity, IUnitOfWorkRepository>();
            deleteEntities = new Dictionary<IEntity, IUnitOfWorkRepository>();
        }

        #endregion

        #region IUnitOfWork 成员
        /// <summary>
        /// 事务提交
        /// </summary>
        public void Commit()
        {
            try
            {
                using (TransactionScope transactionScope = new TransactionScope())
                {

                    foreach (var entity in insertEntities.Keys)
                    {
                        insertEntities[entity].UoWInsert(entity);
                    }
                    foreach (var entity in updateEntities.Keys)
                    {
                        updateEntities[entity].UoWUpdate(entity);
                    }
                    foreach (var entity in deleteEntities.Keys)
                    {
                        deleteEntities[entity].UoWDelete(entity);
                    }
                    transactionScope.Complete();//提交事务,程序中如果出错,这行无法执行,即事务不会被提交,这就类似于rollback机制
                }
            }
            catch (Exception ex)
            {
                Logger.LoggerFactory.Instance.Logger_Error(ex);
            }

        }



        /// <summary>
        /// 注册数据变更
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="type"></param>
        public void RegisterChangeded(IEntity entity, SqlType type, IUnitOfWorkRepository repository)
        {
            switch (type)
            {
                case SqlType.Insert:
                    insertEntities.Add(entity, repository);
                    break;
                case SqlType.Update:
                    updateEntities.Add(entity, repository);
                    break;
                case SqlType.Delete:
                    deleteEntities.Add(entity, repository);
                    break;
                default:
                    throw new ArgumentException("you enter reference is error.");
            }
        }
        #endregion


    }

工作单元在调用时也是非常方便的,两步完成,第一注意动作,第二提交事务,下面看一下DEMO的代码片断

        unitOfWork.RegisterChangeded(entity, SqlType.Update, userRepository);
            var userExtension = userExtRepository.Find(entity.Id);
            userExtension.NickName = Request.Form["UserExtension.NickName"];
            userExtension.School = Request.Form["UserExtension.School"];
            unitOfWork.RegisterChangeded(userExtension, SqlType.Update, userExtRepository);
            unitOfWork.Commit();

OK,对于工作单元的探讨今天就先说到这里,以后肯定还是机会去研究的!

本文转自博客园张占岭(仓储大叔)的博客,原文链接:Lind.DDD.UoW工作单元的实现,如需转载请自行联系原博主。

目录
相关文章
|
10月前
|
消息中间件 架构师 搜索推荐
DDD领域驱动设计的概念解析
DDD领域驱动设计的概念解析
163 0
|
项目管理
DDD案例(1):从需求分析到领域分析(4)
DDD案例(1):从需求分析到领域分析(4)
426 0
DDD案例(1):从需求分析到领域分析(4)
|
JSON 前端开发 数据格式
再议DDD分层
之前整理过《DDD分层》[1] 以及《分层架构》[2] 最近看网友讨论,整理一些有亮点的地方 现在分层架构+整洁架构似乎是个万金油组合了 之前DDD的标准分层结构:
260 0
再议DDD分层
|
设计模式 缓存 Java
DDD之代码架构
这是一篇迟到的文章。这其实是我写DDD的第四篇文章。去年11月份左右我在个人网站上写了三篇关于DDD的文章,都是比较偏战略部分的。那个时候我还在一个正在使用DDD的项目上,也是我第一次真正开始深入使用DDD。
557 1
|
项目管理
DDD案例(1):从需求分析到领域分析(2)
DDD案例(1):从需求分析到领域分析(2)
317 0
DDD案例(1):从需求分析到领域分析(2)
|
数据可视化 Java 程序员
DDD案例(1):从需求分析到领域分析(3)
DDD案例(1):从需求分析到领域分析(3)
292 0
DDD案例(1):从需求分析到领域分析(3)
DDD案例(1):从需求分析到领域分析(5)
DDD案例(1):从需求分析到领域分析(5)
234 0
DDD案例(1):从需求分析到领域分析(5)
|
供应链 数据可视化 Java
DDD案例(1):从需求分析到领域分析(1)
DDD案例(1):从需求分析到领域分析(1)
458 0
DDD案例(1):从需求分析到领域分析(1)
|
供应链 安全 领域建模
DDD案例(1):从需求分析到领域分析(6)
DDD案例(1):从需求分析到领域分析(6)
328 0
DDD案例(1):从需求分析到领域分析(6)
|
数据挖掘 Java 测试技术
DDD领域驱动设计实战(三)-深入理解实体(中)
DDD领域驱动设计实战(三)-深入理解实体(中)
225 0