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