设为首页 加入收藏

TOP

asp.net core系列 62 CQRS架构下Equinox开源项目分析(二)
2019-09-17 18:24:15 】 浏览:67
Tags:asp.net core 系列 CQRS 架构 Equinox 开源 项目 分析
ntity(用户管理如登录、注册、授权)

                     Equinox.Infra.CrossCutting.IoC(控制反转的服务注入)

 

  3. 项目架构流程梳理图

 

 

    流程图更正:领域层Equinox.Domain不需要 引用 基础设施层事件总线Equinox.Infra.CrossCutting.Bus。在DDD风格下领域层是独立的,原则上不依赖于其它层。

    

四.表现层分析

  在表现层是Equinox.UI.Web和Equinox.Services.Api 服务。在Equinox.UI.Web下主要是用控制器中的CustomerController来演示CQRS框架的实现,以及AccountController和ManageController的用户登录、注册、退出和用户信息管理。

  对于AccountController和ManageController两个控制器关联着Equinox.Infra.CrossCutting.Identity项目。Identity项目包括了需要用的视图模型、对系统的授权、自定义用户表数据、用户数据同步到数据库的迁移版本管理、邮件和SMS。对于授权方案通过Equinox.Infra.CrossCutting.IoC来注入服务。如下所示:

        // ASP.NET Authorization Polices
           services.AddSingleton<IAuthorizationHandler, ClaimsRequirementHandler>();

  Equinox.Services.Api项目实现的功能与Web站点差不多,是通过暴露Web API来实现。下面是表现层的二个项目:

  

五. 应用服务层分析

  Equinox.Application应用服务层包括对AutoMapper的配置管理,通过AutoMapper实现视图模型和领域模型的实体互转。定义ICustomerAppService服务接口供表现层调用,由CustomerAppService类来实现该接口。项目包含了Customer需要的视图模型。还有事件源EventSource。

  由CustomerAppService类来实现表现层的查询、命令、获取事件源。项目结构如下:

 

六.领域层Domain.Core分析

  领域层是项目分层架构中,最重要的一层,也是相对复杂的一层。该层作者用了二个项目包括:Domain.Core和Domain项目结构如下所示:

  对于Domain.Core项目主要是定义命令和事件的基类。源头是定义的抽象类Message。对于命令和事件,任何前端都会发送消息给应用程序层, Message消息就是数据传输对象,通常消息定义为一个Message基类开始,作为数据容器。

  这里使用MediatR中间件作为命令和事件的实现。MediatR支持两种消息类型:Request/Response和Notification。先看下Message消息基类定义:

    //注入服务
    services.AddMediatR(typeof(Startup));
    /// <summary>
    /// Message消息 
    /// 放入通用属性,甚至是普通标记,没有属性
    /// </summary>
    public abstract class Message : IRequest<bool>
    {
        /// <summary>
        /// 消息类型:实现Message的命令或事件类型
        /// </summary>
        public string MessageType { get; protected set; }

        /// <summary>
        /// 聚合ID
        /// </summary>
        public Guid AggregateId { get; protected set; }

        protected Message()
        {
            MessageType = GetType().Name;
        }
    }

  

  消息有二种:命令和事件。两种消息都包含了数据传输对象。命令和事件有些微妙差别,命令和事件都是Message派生类。

    /// <summary>
    /// Event 领域消息
    /// 事件类是不可变的,它表示已经发生的事情,意味着只有私有set,没有写入方法。
    /// 事件存放通用属性,例如事件触发时间,触发的用户,数据版本号。
    /// </summary>
    public abstract class Event : Message, INotification
    {
        public DateTime Timestamp { get; private set; }

        protected Event()
        {
            //事件时间
            Timestamp = DateTime.Now;
        }
    }
    /// <summary>
    /// Command领域命令(增删改),不返回任何结果(void),但会改变数据对象的状态。
    /// </summary>
    public abstract class Command : Message
    {
        public DateTime Timestamp { get; private set; }

        //DTO绑定验证,使用Fluent API来实现
        public ValidationResult ValidationResult { get; set; }

        protected Command()
        {
            //命令时间
            Timestamp = DateTime.Now;
        }

        //实现Command抽象类的DTO数据验证
        public abstract bool IsValid();
    }

   

  Domain.Core项目还定义了领域实体和领域值对象的基类实现。例如:在领域实体基类中实现了相等性、运算符重载、重写HashCode。对于实体和值对象主要区别是:实体有明确的身份标识如主键ID,GUID

      public abstract class Entity
      public abstract class ValueObject<T> where T : ValueObject<T>

   

  Domain.Core项目中的Notifications消息文件夹,用来确认消息发送后的处理状态。下面是表现层发送更新命令后,IsValidOperation()确认消息处理的状态情况。

        [HttpPost]
        [Authorize(Policy = "CanWriteCustomerData")]
        [Route("customer-management/edit-customer/{id:guid}")]
        [ValidateAntiForgeryToken]
首页 上一页 1 2 3 4 下一页 尾页 2/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇【原创】代码性能优化之创建对象 下一篇VS 快捷键使用

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目