Ncqrs Framework Reference[翻译]

原文地址

简介

这个参考解释Ncqrs框架是什么,有什么用和怎么用.

Ncqrs是什么

Ncqrs是一个.NET的框架,用于通过支持开发人员应用命令查询职责分离(CQRS)架构模式构建可伸缩,可扩展,可维护的应用程序.它通过提供命令处理和执行,领域建模,事件索源,领域事件,反规范化和事件存储等大部分构建模块实现.这些构建模块帮助你专注于代码和业务逻辑.它支持注释,约定和配置,帮助你编写分离的和可测试的代码.

何时适合使用Ncqrs

Scotty说“How many times do I have to tell you, the right tool for the right job!“.Ncqrs并不适合所有Job.也就是说不是所有应用程序都会从Ncqrs得益.简单的没有多少行为的CRUD系统不适合.但是有非常广泛的系统适合使用Ncqrs.

当系统有一个或多个如下特征时,很可能就会适合:

  • Long life time-项目将在一个较长的周期或时间存在,所以需要有机地发展.
  • 需要可扩展的(scalable)-当需要时系统能被扩展.
  • 包含业务逻辑-系统包含业务逻辑,需要保留可维护性.
  • 需求整合-其它系统能够整合它.
  • 多视图-数据的视图有多种屏幕,报告和应用.
  • 必须有一个审计日志-所有的状态改变都要记录和需要构建一个审计日志.

系统需求

要使用Ncqrs框架需要.NET Framework 3.5或者更高版本.

架构

Ncqrs帮助开发者应用命令查询职责分离(CQRS)架构模式.这个模式本身是非常简单的.它的意思是查询进程应该模块应该与命令进程模块分开.应用这个模式也会引申出其它几个NB的模式.Ncqrs提供了这些模式的构件块的实现.这幅图展示了应用可这个模式的应用程序的普通架构.

Ncqrs system architecture

首先,你应该注意到获取数据和修改数据是有区别的;分开read side 和 write side.上图顶部的用户界面组件发送命令到命令handlers.命令handlers改变领域.领域的改变触发事件同时这些事件被存储到事件仓库,事件同时同时也被推送到denormalizers.denormalizers denormalize这些事件来改变read models.通过这种方法来使read models更新.用户界面使用read models来查询数据.

命令处理

用户界面通过发送命令来改变系统.命令是要执行的Action所需要的全部数据.例如MoveUserToNewAddress.这个命令应该持有一个用户的新地址和一个表明那个需要move的用户id.

命令也通过它的名字表明目的.例如尽管命令MoveUserToNewAddress和CorrectAddressForUser包含相同的数据-address和用户id,但是目的是不同的.

所有的命令都会发送到一个命令服务.这个服务接受一个命令同时把它路由到正确的命令executors.所有的命令executors响应一个特殊的命令和执行在命令内容基础上的Action.

Ncqrs提供构建模块来帮助你非常轻松地实现一个命令服务,以横切关注点的扩展点的形式,例如验证和日志.

命令executors不应该包含业务逻辑.唯一要做的就是从领域中更改聚合根和改变它们.为远离管道代码,Ncqrs为命令提供映射,可将命令直接映射到一个领域对象.

领域

命令executors在领域里改变聚合根.在这些对象中捕获所有业务逻辑同时不需要查询.这就允许我们最优化model的行为.

聚合根包含真正的业务逻辑和负责守着自己的不变量.聚合根的状态改变会引发领域事件.领域事件的队列代表它的所有已做的改变.这个模式叫event sourcing(事件索源).

领域事件

领域里的所有状态的改变表现为领域事件.它们是包含所有用于描述变化的数据的简单对象.我们给出过两个例子(MoveUserToNewAddress和CorrectAddressForUser).事件与这些命令的状态变化有关系.注意事件的名称是过去式的.

仓储

仓储是用作获取和保存聚合根的.通过它们的事件实现.当有变化时,保存一个聚合根会导致持久化所有未提交的事件.获取一个聚合根是通过获取这个事件和重置它们来把聚合根建立到最新状态.

当一个聚合根被保存,事件会被储存在事件仓库里,所有的事件也会被推送到事件仓库.

事件仓库

所有已发生的事件都会送到事件仓库.它包含表示系统中的状态更改的所有事件.它们可以用于以重播的方式构建当前状态.事件仓储也可以用于填补或修复已存在的read model.

Ncqrs当前支持一下的产品在为事件仓库.

事件总线

当一个聚合根通过仓储保存所有未提交的事件时,表示状态已经变化,已被持久化到事件仓库。另外,仓储依然通过事件总线推送这些事件.总线会推送到每一个注册了的对它感兴趣的事件.这里要做一个非常重要的决定,总线用同步还是异步的方式推送这些事件给订阅者.

同步即订阅者所做的事件处理会阻塞当前的执行,返回给用户前它会等待所有订阅者完成.这种模式简单,是默认模式.

异步在返回给用户前不会等待所有订阅者完成.它会在总线里终止事件和返回给用户.它会保持命令的快速执行,但是引入eventual consistency问题.read models会在一些时间点一致的(consistent).

事件handlers

会有不同的事件handlers订阅事件总线.最普通的是denormalizers.这些事件handlers执行事件和它们的基础上改变read model.例如,一个denormalizer会以UserMovedToNewAddress事件中的数据为基础更新用户表的用户地址.但是它也会在同一事件中更新城市X的总用户数.

事件handlers不但对保持read model最新感兴趣.它也去改变外部系统或者当发送事件错误时发送一封警告邮件.一个事件handler也可能引出一个新的命令.事件handlers扩展系统一个新功能而不用改变原系统的重要部分.

Read models

数据是每一个系统的重要组成部分.大部分用户界面页面都要请求数据.每个页面对数据都有不同的要求.例如,有个页面想要所有的产品的名称,价格和分类,但另一个想要产品的名称和最新的3个产品review score和reviewer的名称.

Read models是最优化数据查询的models.那么什么是最优化查询?就是一个只查询一个源的查询.换句话说:select * from x where y.没有joining,只给我这个数据.通过为每个页面创建一个表实现.这样每个页面就能做到用简单查询请求数据.

你的read model不一定要求关系数据库,它可以是包含每个视图的集合的基于数据库的文档.

Ncqrs只为denormalizers提供了一个允许订阅事件总线的基类.denormalization本身是简单和明确的.

最终的应用程序流程

PS

水平不行,有几个地方不会译.

下面那的例子不译了.

原文地址:https://www.cnblogs.com/lemontea/p/2252060.html