项目分层以及依赖关系

领域模型层

基础设施层

应用层

共享层

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);
        }
    }
领域对象实现

相关文章: