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,对于工作单元的探讨今天就先说到这里,以后肯定还是机会去研究的!

回到目录

posted @ 2015-12-28 20:46  张占岭  阅读(2413)  评论(0编辑  收藏  举报