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

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

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);
        }
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏好好学java的技术栈

java爬虫带你爬天爬地爬人生,爬新浪

HttpClient是Apache Jakarta Common下的子项目,可以用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,并且它支持...

1772
来自专栏木宛城主

庖丁解牛看委托和事件(续)

上一篇文章:庖丁解牛——深入解析委托和事件之后,以一题面试题来总结事件 using System; using System.Collections.Gener...

3719
来自专栏LeoXu的博客

org.apache.http.client.methods.HttpPost 两种消息体形式 —— UrlEncodedFormEntity 和 StringEntity

使用 UrlEncodedFormEntity 来设置 body,消息体内容类似于“KEY1=VALUE1&KEY2=VALUE2&...”这种形式,服务端接收...

2302
来自专栏Create Sun

quartz.net插件类库封装(含源码)

1、前言    最近项目需要做一写任务作业调度的工作,最终选择了quartz.net这个插件,它提供了巨大的灵活性而不牺牲简单性。你能够用它来为执行一个作业而 ...

28911
来自专栏码农阿宇

.Net Core下 Redis的String Hash List Set和Sorted Set的例子

1.新建一个.Net Core控制台应用程序,用Nuget导入驱动 打开程序包管理控制台, ? 执行以下代码。 PM> Install-Package Serv...

3887
来自专栏hbbliyong

Extjs4处理后台json数据中日期和时间的方法

当ASP.NET后台使用JavaScriptSerializer这个组件将对象序列化为json,或者使用ScriptMethod特性的json      [Sc...

3867
来自专栏Java职业技术分享

java爬虫带你爬天爬地爬人生,爬新浪

HttpClient是Apache Jakarta Common下的子项目,可以用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,并且它支持...

1565
来自专栏张善友的专栏

.NET 4 System.Threading.CountdownEvent

在Visual Studio 2010 and .NET Framework 4 Training Kit中有个System.Threading.Countdo...

1808
来自专栏JadePeng的技术博客

使用Mongodb 做对象缓存

mongodb高效的访问速度,用来快速存取数据再合适不过了,缓存神马的,可以用这个的 另外,有的时候,如果仅仅存储几条数据,单独去建立一张表代价太大,这个时候,...

4695
来自专栏跟着阿笨一起玩NET

NPOI简述与运用

最近想把项目中Excel中的操作部分改成NPOI ,由于2.0版本已经支持office07/10格式,但还处于测试版不稳定,于是封装如下代码

1181

扫码关注云+社区

领取腾讯云代金券