用户层:
1.请求应用层获取用户显示的信息
2.发送命令给应用层要求执行某个命令
应用层:
对用户界面提供各种应用功能(包括信息获取与命令执行),应用层不包含业务逻辑,业务层是由应用层调用领域层(领域对象或领域服务)来完成的,应用层是很薄的一层
领域层:
包含领域对象和领域服务,完成系统所需的业务处理,是系统的核心。业务逻辑与仓储接口都在领域层
基础机构层:
包含其他层所需要使用的所有基础服务与技术,比如仓储的实现(与数据打交道)、短消息发送、Json字符串处理
工作单元:
保证聚合间的一致性
通常在领域服务或应用服务中使用工作单元
仓储实现不用考虑数据库事务
一般通过应用层访问仓储,而且是使用领域层定义的仓储接口,具体仓储的实现调用可以通过IOC的机制在应用层通过服务定位器模式找到。
一般不要在领域层访问仓储,如果领域层中的领域对象或领域服务的业务逻辑处理确实需要访问仓储,建议不通过服务定位器的方式在领域层进行服务解析,
而是应该在领域对象或领域服务的构造函数中传入仓储接口,具体是哪个仓储实现,仍然在服务层通过应用模式找到,这样保证服务层只关注业务,而不关注其他方面
一些界面需要获取的查询信息,不应该通过领域对象直接返回给应用服务层,应该在应用 层实现DTO
代码:
/// <summary> /// 仓储的接口 维护这个接口里面的状态 /// </summary> /// <typeparam name="TAggreateRoot"></typeparam> public interface IRepository<TAggreateRoot> where TAggreateRoot:class, IAggreateRoot { void Create(TAggreateRoot aggreateroot); TAggreateRoot GetByID(Guid id); List<TAggreateRoot> GetByCondition(Expression<Func<TAggreateRoot, bool>> condition); void Update(TAggreateRoot aggreateroot); void Remove(TAggreateRoot aggreateroot); void RemovdByID(Guid id); }
/// <summary> /// 仓储上下文的接口 全部放到上下文中 通过工作单元 一起提交 /// IDisposable 定时释放资源 /// </summary> public interface IRepositoryContext:IUnitOfWork,IDisposable { //创建对象的集合 void RegisterCreate<TAggreateRoot>(TAggreateRoot aggreateroot) where TAggreateRoot : class, IAggreateRoot; //修改 void RegisterUpdate<TAggreateRoot>(TAggreateRoot aggreateroot) where TAggreateRoot : class, IAggreateRoot; //删除 void RegisterRemove<TAggreateRoot>(TAggreateRoot aggreateroot) where TAggreateRoot : class, IAggreateRoot; Guid ContextID { get; } }
public interface IUnitOfWork { void Commit(); void RollBack(); //是否提交 bool Committed { get; set; } }
仓储上下文:
public abstract class RepositoryContext : IRepositoryContext, IDisposable { //保证线程本地化 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 virtual void RegisterCreate<TAggreateRoot>(TAggreateRoot aggreateroot) where TAggreateRoot : class, IAggreateRoot { if (aggreateroot.Id.Equals(Guid.Empty)) { throw new AggregateException("聚合根ID不能为空"); } if (localcreatedics.Value.ContainsKey(aggreateroot.Id)) { throw new InvalidOperationException("新创建的领域对象已经存在在集合中"); } //向集合总提交 聚合根的id 和聚合根 localcreatedics.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 AggregateException("聚合根ID不能为空"); } if (localupdatedics.Value.ContainsKey(aggreateroot.Id)) { throw new InvalidOperationException("更新的领域对象已经存在在集合中"); } if (localremovedics.Value.ContainsKey(aggreateroot.Id)) { throw new InvalidOperationException("领域对象正在被更新,不能删除"); } localremovedics.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 Guid ContextID { get { return Guid.NewGuid(); } } public abstract void Commit(); /// <summary> /// 提交的属性 /// </summary> public bool Committed { get { return localcommitted.Value; } set { localcommitted.Value = value; } } /// <summary> /// 释放资源 /// </summary> public virtual void Dispose() { localcreatedics.Dispose(); localupdatedics.Dispose(); localremovedics.Dispose(); localcommitted.Dispose(); } //在仓储中具体实现 public abstract void RollBack(); }
具体的实现 :
/// <summary> /// 仓储类的实现 /// </summary> public class EFRepository<TAggreateRoot> : EFRepositoryContext, IRepository<TAggreateRoot> where TAggreateRoot :class,IAggreateRoot { public void Create(TAggreateRoot aggreateroot) { base.RegisterCreate(aggreateroot); } public List<TAggreateRoot> GetByCondition(Expression<Func<TAggreateRoot, bool>> condition) { throw new NotImplementedException(); } public TAggreateRoot GetByID(Guid id) { throw new NotImplementedException(); } public void RemovdByID(Guid id) { throw new NotImplementedException(); } public void Remove(TAggreateRoot aggreateroot) { base.RegisterRemove(aggreateroot); } public void Update(TAggreateRoot aggreateroot) { base.RegisterUpdate(aggreateroot); } }
仓储上线文的实现:
/// <summary> /// 仓储上下文的实现 /// </summary> public class EFRepositoryContext : RepositoryContext { public override void RegisterCreate<TAggreateRoot>(TAggreateRoot aggreateroot) { base.RegisterCreate<TAggreateRoot>(aggreateroot); Committed = false; } public override void RegisterRemove<TAggreateRoot>(TAggreateRoot aggreateroot) { base.RegisterRemove<TAggreateRoot>(aggreateroot); Committed = false; } public override void RegisterUpdate<TAggreateRoot>(TAggreateRoot aggreateroot) { base.RegisterUpdate<TAggreateRoot>(aggreateroot); Committed = false; } public override void Commit() { Committed = true; } public override void RollBack() { Committed = true; } public override void Dispose() { base.Dispose(); } }
判断ID:
public interface IEntity { Guid Id { get; } }
public interface IAggreateRoot:IEntity { }
public abstract class AggreateRoot:Entity { }
public abstract class Entity : IEntity { public Guid Id { get { var id = Guid.NewGuid(); return id; } } /// <summary> /// 比较两个对象 /// </summary> /// <param name="obj"></param> /// <returns></returns> public override bool Equals(object obj) { if (obj == null) { return false; } //判断两个实列是否相等 if (ReferenceEquals(this, obj)) { return true; } //判断ID是否相等 return this.Id == (obj as IEntity).Id; } public override int GetHashCode() { return this.Id.GetHashCode(); } }