CQRS 和 DDD:文件上传

CQRS and DDD: File uploads

我是 DDD 和 CQRS 概念的新手,找不到如何以干净的方式上传图像或一般文件的最终解决方案。

想象一下以下场景: 在在线门户中有一个支持请求公式,其中可以附加文件(特定图像)。 发布的数据将引发CreateSupportRequestCommand。然后将加载和更改所需的聚合。

我有三个想法来解决这个问题,但我对它们不是很满意。

方式一:
1. Post 单个请求中包含图像(多部分)的所有数据
2. 创建一个 FileUploadCommand,它是 returning FileUploadId.
3. 之后创建一个 CreateSupportRequestCommand 并在构造函数中传递带有根数据的 FileUploadId
缺点:单个请求会触发两个命令。就 CQRS 而言,一个用户交互应该只是一个命令。

方式二:
1. Post 图像到一个单独的端点,创建一个临时文件和 return id 或文件句柄。
2. Post 带有附加临时文件 ID 的公式。
3. 使用所有根数据调用 CreateSupportRequestCommand,包括指向物理文件的文件句柄。
4. 在命令内部将临时文件保存到 FileUpload 聚合中(通过 FileUploadRepository)然后
5. 创建 SupportRequest 聚合,分配 FileUploadId 并保留。
缺点:我在同一命令中处理 2 个聚合。创建支持请求不负责上传文件。

方式三: 1. Post 图像到一个单独的端点,创建一个临时文件和 return id 或文件句柄。
2. Post 带有附加临时文件 ID 的公式。
3. 使用所有根数据调用 CreateSupportRequestCommand,包括指向物理文件的文件句柄。
4. 只将根数据持久化到SupportRequest聚合。提出一个 SupportRequestCreatedEvent 并附上文件句柄。
5. 在事件进程中分配文件句柄。
缺点:SupportRequestCreatedEvent 不应该真正关心文件句柄。

有没有更好的方法解决这个问题?

我不认为处理文件上传是一个领域问题。 FileContentId 等文件元数据可能是您域的一部分,但不是实际上传的文件。我会在执行 CommandHandler 之前执行文件操作。可能在中间件中,或者可能在将 Command 排队到消息总线之前。

CreateSupportRequestCommandHandler 只会在您的聚合上调用 operation 之类的 CreateSupportRequest(比如 SupportRequest)。在该 CreateSupportRequest 方法中,您将所有业务规则都保留到该操作中。 SupportRequest 然后最终将保存在您的存储库中。