zoukankan      html  css  js  c++  java
  • 领域驱动设计案例之仓储顶层实现

    在业务中,我们会涉及到对象的创建、重建、更新、销毁等操作,这些操作通常需要持久化到数据库中,我们通过仓储来实现对数据的访问

    1.首先我们要实现仓储上下文,仓储上下文主要是维护一些创建、更新、销毁的对象列表,未来可以实现批量持久化,从而保持多实体与多聚合的事务,从而实现内部一致性和外部一致性:

    using Order.Domain.Aggreate;
    using Order.Domain.Repository;
    using System;
    using System.Collections.Generic;
    using System.Threading;
    
    namespace Order.Repositories
    {
        public abstract class RepositoryContext : IRepositoryContext, IDisposable
        {
            private readonly Guid contextid = Guid.NewGuid();
            private readonly ThreadLocal<Dictionary<Guid, object>> localcreatedics =
                new ThreadLocal<Dictionary<Guid, object>>();
            private readonly ThreadLocal<Dictionary<Guid, object>> localupdatedics =
                new ThreadLocal<Dictionary<Guid, object>>();
            private readonly ThreadLocal<Dictionary<Guid, object>> localremovedics =
        new ThreadLocal<Dictionary<Guid, object>>();
            
            //集合中默认所有内容标记为已提交
            private readonly ThreadLocal<bool> localcommitted = new ThreadLocal<bool>(() => true);
            public bool Committed
            {
                get { return localcommitted.Value; }
                set { localcommitted.Value = value; }
            }
    
            public Guid ContextId
            {
                get { return contextid; }
            }       
    
            /// <summary>
            /// 由继承类再实现
            /// </summary>
            public abstract void Commit();
            public abstract void RollBack();
            
    
            public virtual void Dispose()
            {
                localcreatedics.Dispose();
                localupdatedics.Dispose();
                localremovedics.Dispose();
                localcommitted.Dispose();
            }
    
            public virtual void RegisterCreate<TAggreateRoot>(TAggreateRoot aggreateroot) where TAggreateRoot : class, IAggreateRoot
            {
                if (aggreateroot.Id.Equals(Guid.Empty))
                    throw new ArgumentException("对象ID为空");
                if (localcreatedics.Value.ContainsKey(aggreateroot.Id))
                    throw new InvalidOperationException("此对象已在创建集合中");
                localcreatedics.Value.Add(aggreateroot.Id, aggreateroot);
                //创建的对象添加到集合中,并且设置状态为未提交
                localcommitted.Value = false;
            }
    
            public virtual void RegisterRemove<TAggreateRoot>(TAggreateRoot aggreateroot) where TAggreateRoot:class,IAggreateRoot
            {
                if (aggreateroot.Id.Equals(Guid.Empty))
                    throw new ArgumentException("对象ID为空");
                if (localremovedics.Value.ContainsKey(aggreateroot.Id))
                    throw new InvalidOperationException("此对象已在删除集合中");
                if (localupdatedics.Value.ContainsKey(aggreateroot.Id))
                    throw new InvalidOperationException("此对象正在被修改,不能添加到删除集合中");
                localremovedics.Value.Add(aggreateroot.Id, aggreateroot);
                localcommitted.Value = false;
            }
    
            public virtual void RegisterUpdate<TAggreateRoot>(TAggreateRoot aggreateroot) where TAggreateRoot:class,IAggreateRoot
            {
                if (aggreateroot.Id.Equals(Guid.Empty))
                    throw new ArgumentException("对象ID为空");
                if (localupdatedics.Value.ContainsKey(aggreateroot.Id))
                    throw new InvalidOperationException("此对象已在更新集合中");
                if (localremovedics.Value.ContainsKey(aggreateroot.Id))
                    throw new InvalidOperationException("此对象正在被删除,不能添加到更新集合中");            
                localupdatedics.Value.Add(aggreateroot.Id, aggreateroot);
                localcommitted.Value = false;
            }
        }
    }

    因为我们这里最终会使用EF作为对象列表状态维护以及最终提交到持久化存储,所以我们实现一个EF的仓储上下文,使用EF的机制来维护与提交:

    using Order.Domain.Model;
    using System.Threading;
    using System.Data.Entity;
    
    
    namespace Order.Repositories
    {
        public class EFRepositoryContext : RepositoryContext
        {
            private readonly ThreadLocal<OrdersContainer> orderdbcontext =
                new ThreadLocal<OrdersContainer>(() => new OrdersContainer());
           
            public DbContext OrderDbContext { get { return orderdbcontext.Value; } }
            public override void RegisterCreate<TAggreateRoot>(TAggreateRoot aggreateroot)
            {
                orderdbcontext.Value.Set<TAggreateRoot>().Add(aggreateroot);
                Committed = false;
            }
            public override void RegisterUpdate<TAggreateRoot>(TAggreateRoot aggreateroot)
            {
                orderdbcontext.Value.Entry<TAggreateRoot>(aggreateroot).State =
                    EntityState.Modified;
                Committed = false;
            }
            public override void RegisterRemove<TAggreateRoot>(TAggreateRoot aggreateroot)
            {
                orderdbcontext.Value.Set<TAggreateRoot>().Remove(aggreateroot);
                Committed = false;
            }
            public override void Commit()
            {
                if (!Committed)
                    orderdbcontext.Value.SaveChanges();
                Committed = true;
            }
    
            public override void RollBack()
            {
                Committed = false;
            }
    
            public override void Dispose()
            {
                if (!Committed)
                    Commit();
                orderdbcontext.Value.Dispose();
                orderdbcontext.Dispose();
                base.Dispose();
            }
        }
    }

    2.然后我们要实现仓储,仓储主要进行对象的创建、重建、更新和销毁,其中创建、更新和销毁通过仓储上下文实现批量持久化:

    using Order.Domain.Aggreate;
    using Order.Domain.Repository;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Data;
    
    namespace Order.Repositories
    {
        public abstract class EFRepository<TAggreateRoot> : EFRepositoryContext,IRepository<TAggreateRoot>
            where TAggreateRoot:class,IAggreateRoot
        {
            public void Create(TAggreateRoot aggreateroot)
            {
                base.RegisterCreate<TAggreateRoot>(aggreateroot);
            }
    
            public List<TAggreateRoot> GetbyCondition(Expression<Func<TAggreateRoot, bool>> condition)
            {
                return OrderDbContext.Set<TAggreateRoot>()
                    .Where(condition).ToList();
            }
    
            public TAggreateRoot GetbyId(Guid id)
            {
                return OrderDbContext.Set<TAggreateRoot>().
                    Where(p=>p.Id==id).SingleOrDefault();
            }
    
            public void Remove(TAggreateRoot aggreateroot)
            {
                base.RegisterRemove<TAggreateRoot>(aggreateroot);
            }
    
            public void RemoveById(Guid id)
            {
                var aggreateroot = OrderDbContext.Set<TAggreateRoot>().
                    Where(p => p.Id == id).SingleOrDefault();
                Remove(aggreateroot);
            }
          
            public void Update(TAggreateRoot aggreateroot)
            {
                base.RegisterUpdate<TAggreateRoot>(aggreateroot);
            }
        }
    }

     欢迎加入QQ讨论群:309287205

  • 相关阅读:
    存在和本质
    数据库的日志机制
    【msql】关于redo 和 undo log
    乐观锁是基于比较的无锁并发控制机制
    两段锁协议和防止死锁的一次封锁法
    并发编程沉思录
    什么是B-Tree
    二叉树与b树的性能区别:计算、层级与io
    认知模型
    复杂性、认知与心理学
  • 原文地址:https://www.cnblogs.com/malaoko/p/5000211.html
Copyright © 2011-2022 走看看