前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >领域驱动设计案例之仓储顶层实现

领域驱动设计案例之仓储顶层实现

作者头像
用户1910585
发布2018-05-11 15:30:03
1.1K0
发布2018-05-11 15:30:03
举报
文章被收录于专栏:领域驱动设计DDD实战进阶

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

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

代码语言:javascript
复制
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的机制来维护与提交:

代码语言:javascript
复制
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.然后我们要实现仓储,仓储主要进行对象的创建、重建、更新和销毁,其中创建、更新和销毁通过仓储上下文实现批量持久化:

代码语言:javascript
复制
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);
        }
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015-11-27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档