设为首页 加入收藏

TOP

asp.net core系列 62 CQRS架构下Equinox开源项目分析(三)
2019-09-17 18:24:15 】 浏览:68
Tags:asp.net core 系列 CQRS 架构 Equinox 开源 项目 分析
public IActionResult Edit(CustomerViewModel customerViewModel) { if (!ModelState.IsValid) return View(customerViewModel); _customerAppService.Update(customerViewModel); if (IsValidOperation()) ViewBag.Sucesso = "Customer Updated!"; return View(customerViewModel); }

  

  Domain.Core项目中的Bus文件夹,用来做命令总线和事件总线的发送接口,由Equinox.Infra.CrossCutting.Bus项目来实现总线接口的发送。

 

七.领域层Domain分析

  下面是Domain项目结构如下:

  在上面结构中,Commands和Events文件夹分别用来存储命令和事件的数据传输对象,是贫血的DTO类,也可以理解为领域实体。例如Commands文件夹下命令数据传输对象定义:

     /// <summary>
    /// Customer数据转输对象抽象类,放Customer通过属性
    /// </summary>
    public abstract class CustomerCommand : Command
    {
        public Guid Id { get; protected set; }

        public string Name { get; protected set; }

        public string Email { get; protected set; }

        public DateTime BirthDate { get; protected set; }
    }
    /// <summary>
    /// Customer注册命令消息参数
    /// </summary>
    public class RegisterNewCustomerCommand : CustomerCommand
    {
        public RegisterNewCustomerCommand(string name, string email, DateTime birthDate)
        {
            Name = name;
            Email = email;
            BirthDate = birthDate;
        }

           /// <summary>
        /// 命令信息参数验证
        /// </summary>
        /// <returns></returns>
        public override bool IsValid()
        {
            ValidationResult = new RegisterNewCustomerCommandValidation().Validate(this);
            return ValidationResult.IsValid;
        }
    }

   

  当在应用服务层发送命令(Bus.SendCommand)后,由领域层的CommandHandlers文件夹下的类来处理命令,再调用EF持久层来改变实体状态。下面梳理下命令的执行流程,由表现层开始一个customer新增如下所示

    当在表现层点击Create后,调用应用服务层Register方法,触发一个新增事件,代码如下:

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="customerViewModel">视图模型</param>
        public void Register(CustomerViewModel customerViewModel)
        {
            //将视图模型 映射到  RegisterNewCustomerCommand 新增命令实体
            var registerCommand = _mapper.Map<RegisterNewCustomerCommand>(customerViewModel);
            Bus.SendCommand(registerCommand);
        }

     当SendCommand发送命令后,由领域层CustomerCommandHandler类中的Handle来处理该命令,如下所示:

         /// <summary>
        /// Customer注册命令处理
        /// </summary>
        /// <param name="message"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public Task<bool> Handle(RegisterNewCustomerCommand message, CancellationToken cancellationToken)
        {
            //对实体属性进行验证
            if (!message.IsValid())
            {
                NotifyValidationErrors(message);
                return Task.FromResult(false);
            }

            //将命令消息转成领域实体
            var customer = new Customer(Guid.NewGuid(), message.Name, message.Email, message.BirthDate);

            //如果注册用户邮件已存在,发起一个事件
            if (_customerRepository.GetByEmail(customer.Email) != null)
            {
                Bus.RaiseEvent(new DomainNotification(message.MessageType, "The customer e-mail has already been taken."));
                return Task.FromResult(false);
            }

            //由Equinox.Infra.Data.Repository来实现数据持久化。事件是过去在系统中发生的事情。该事件通常是命令的结果.
            _customerRepository.Add(customer);

            //新增成功后,使用事件记录这次命令。
            if (Commit())
            {
                Bus.RaiseEvent(new CustomerRegisteredEvent(customer.Id, customer.Name, customer.Email, customer.BirthDate));
            }

            return Task.FromResult(true);
        } 

    下面是注册customer的信息,以及注册产生的事件数据,如下所示:

 

  在领域层的Interfaces文件夹中,最重要的包括IRepository&l

首页 上一页 1 2 3 4 下一页 尾页 3/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇【原创】代码性能优化之创建对象 下一篇VS 快捷键使用

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目