项目分层以及依赖关系
领域模型层
基础设施层
应用层
共享层
1、共享层
XXX.Core:基础项目
基础类型比如说异常或者帮助类等。不应该依赖任何项目。
XXX.Domain.Abstractions:领域抽象层
在领域模型中可以定义一些entity基类 接口 或者领域事件的接口等等。不应该依赖任何项目。
XXX.Infrastructure.Core:基础设施核心层
可以对我们的领域仓库还有我们EFContext定义一些基础共享的代码。
依赖沃恩的领域模型抽象层,实现了我们的仓储
2、领域模型层
目的:专注于业务的设计,不依赖仓储等记住设置层。就是我们理解的实体层
XXX.Domain
里面会有不同的领域聚合,领域事件。
领域对象需要继承领域抽象层,并实现一个聚合根的接口 表明他是一个聚合根。
领域事件需要实现领域事件的接口
3、基础设施层
目的:他的仓库负责领域模型的存取,不负责任何业务代码
XXX.Infrastructure
就是我们实现的仓库(比如说 订单仓库等等)和一些共享代码的实现。
数据库访问的实现:
事务处理的实现:
4、应用层
可以分为两个
XXX.API:接口
XXX.BackgroundTasks:后台任务
推荐:
使用CQRS模式
WEBAPI是面向前端交互的接口,避免依赖领域模型。
领域模型设计
分为领域模型的抽象层和领域模型的实现
一、领域模型抽象层
1、聚合根接口,实现他的表明是一个聚合根。
public interface IAggregateRoot { }
2、领域对象的接口
public interface IEntity { object[] GetKeys(); } public interface IEntity<TKey> : IEntity { TKey Id { get; } }
3、领域对象的实现。里面定义了一些领域对象的公用方法。
public abstract class Entity : IEntity { public abstract object[] GetKeys(); public override string ToString() { return $"[Entity: {GetType().Name}] Keys = {string.Join(",", GetKeys())}"; } #region private List<IDomainEvent> _domainEvents; public IReadOnlyCollection<IDomainEvent> DomainEvents => _domainEvents?.AsReadOnly(); public void AddDomainEvent(IDomainEvent eventItem) { _domainEvents = _domainEvents ?? new List<IDomainEvent>(); _domainEvents.Add(eventItem); } public void RemoveDomainEvent(IDomainEvent eventItem) { _domainEvents?.Remove(eventItem); } public void ClearDomainEvents() { _domainEvents?.Clear(); } #endregion } public abstract class Entity<TKey> : Entity, IEntity<TKey> { int? _requestedHashCode; public virtual TKey Id { get; protected set; } public override object[] GetKeys() { return new object[] { Id }; } public override bool Equals(object obj) { if (obj == null || !(obj is Entity<TKey>)) return false; if (Object.ReferenceEquals(this, obj)) return true; if (this.GetType() != obj.GetType()) return false; Entity<TKey> item = (Entity<TKey>)obj; if (item.IsTransient() || this.IsTransient()) return false; else return item.Id.Equals(this.Id); } public override int GetHashCode() { if (!IsTransient()) { if (!_requestedHashCode.HasValue) _requestedHashCode = this.Id.GetHashCode() ^ 31; return _requestedHashCode.Value; } else return base.GetHashCode(); } //表示对象是否为全新创建的,未持久化的 public bool IsTransient() { return EqualityComparer<TKey>.Default.Equals(Id, default); } public override string ToString() { return $"[Entity: {GetType().Name}] Id = {Id}"; } public static bool operator ==(Entity<TKey> left, Entity<TKey> right) { if (Object.Equals(left, null)) return (Object.Equals(right, null)) ? true : false; else return left.Equals(right); } public static bool operator !=(Entity<TKey> left, Entity<TKey> right) { return !(left == right); } }