我目前正在开发一个整体系统,我希望将其引入现代并结合 DDD 和 CQRS。我收到了重新编写解决方案的导入机制的请求,并认为这可能是开始此重新架构过程的好机会。
目前流程是:
- 用户上传 CSV
- 系统解析 CSV 并在屏幕上显示每一行。对每一行以及与每一行相关的错误/警告进行验证
- 用户可以修改每一行并重新验证所有行
- 然后,用户选择没有错误的行并提交导入
- 行导入,任何未选定的行或有错误的行都会进入保留区域,以便他们可以在以后处理它们
额外的细节是多行可以属于同一实体(例如,2 行可以是订单中的行项目,因此将具有相同的订单参考)。
我正在考虑有一个导入传奇,它会生成一堆导入聚合(例如 OrderImportAggregate),然后当提交导入时,这些聚合将被转换为当前在系统中使用的类,这有望成为其本身的聚合当进一步重新架构时!因此,传奇过程将采取以下方式:
- [EntityType]FileImportUploaded - 存储 CSV
- [EntityType]FileImportParsed - 生成 n 个 [EntityType]Import 聚合。[EntityType]ImportItemCreated 引发/处理的事件
- 流程将调用当前实体所经历的验证例程来生成错误列表(如果有),并针对每个项目进行存储。 [EntityType]ImportItemValidated 事件引发/处理
- 每次在屏幕上更改一行时,它都会调用 saga 和项目 id 的 Web API 方法来更新详细信息并按照第 3 点重新验证该行。
- User submits import, service groups entities together, based on ref for example, they get converted into the current system entity and calls their import/save routine. [EntityType]ImportItemCompleted event raised.
- 当所有聚合都处于 ImportItemComplete 状态时,Saga 完成
由于这是我第一次实现 CQRS/Event Sourcing/DDD,因此我想从正确的基础开始,所以想知道这是否是该功能所需的方法?
我建议您将域分成两个单独的子域,分别实现为单独的有界上下文,其中一个有界上下文是Import bounded context
(ImportBC
),另一个是receiving bounded context
(ReceivingBC
,实际名称我不知道,请相应替换)。
然后,在Import BC
你应该使用CRUD
风格,每个导入文件都有一个实体,并使用持久性remember验证和导入过程的进度(该实体包含尚未导入的项目的列表)。每个项目经过人工验证后,可以将命令发送到ReceivindBC
根据业务规则测试聚合是否有效,但无需将更改提交到存储库!这样做是为了让人类用户知道该项目是否确实有效并启用/禁用import button
。通过这种方式,您就不会在两个有界上下文中重复验证逻辑。当用户实际按下import button
将导入命令发送到聚合中ReceivingBC
并且您实际上将更改提交到存储库。此外,您还可以从import file CRUD entity
.
这种发送命令但实际上不持久保存到存储库中的技术对于帮助用户体验 in the UI
(不重复内部逻辑UI
),如果你遵循DDD
最佳实践并将您的聚合设计为纯粹的、无副作用的对象(与存储库无关,不知道它们的存在,根本不使用它们!)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)