在 AxonIQ 中放置域服务的位置
Where to place domain services in AxonIQ
我有一个用户聚合,它是使用 CreateUser 命令创建的,它由聚合标识符和用户名组成。
除此之外,我还有与 mongo 数据库通信的域服务,并检查用户名是否存在,如果不存在,则将其放在那里。
例如 registerUsername(username) -> true / false 是否注册了
我的问题是,在将处理 CreateUser 命令的用户聚合之上创建命令处理程序是否是个好主意,无论它是否具有用户名都会正确调度 commands/events?像这样:
@Component
class UserCommandHandler(
@Autowired
private val repository: Repository<User>,
@Autowired
private val eventBus: EventBus,
@Autowired
private val service: UniqueUserService
) {
@CommandHandler
fun createUser(cmd: CreateUser) {
if (this.service.registerUsername(cmd.username)) {
this.repository.newInstance { User(cmd.id) }
.handle(GenericCommandMessage(cmd))
} else {
this.eventBus.publishEvent(UserCreateFailed(cmd.id, cmd.username))
}
}
}
这个问题不一定与 ddd 中的集合唯一性有关,但更多的是一个问题,我应该在哪里放置域服务的依赖项?我可能可以创建用户注册 saga 并将该服务注入 saga 但我认为 saga 应该只依赖于命令调度并且没有任何 if/else 逻辑。
我认为放置域服务的位置取决于手头的用例。
我通常尝试让域服务完全不对其他服务或数据库进行虚拟出站调用。
您现在设想的域服务正是这样做的,就像您指出的那样,解决了唯一性问题。
在这种情况下,您可能会采用建议的方法。
您还可以考虑引入一个 MessageHandlerInterceptor
(或者更高级的 HandlerEnhancerDefinition
,如 here 所述),专门触发创建命令并执行所需的检查。
如果它是像我刚才描述的那样的域服务(例如来自域服务的零出站调用),那么您可以安全地将它连接到您的命令处理函数中以执行某些操作。
如果您处于 Spring 环境中,只需将您的域服务作为一个 bean 并将其作为参数提供给您的消息处理函数就足以让 Axon 为您解决它(通过ParameterResolvers
,如 here 所述)。
希望这对您有所帮助@PolishCivil!
我有一个用户聚合,它是使用 CreateUser 命令创建的,它由聚合标识符和用户名组成。
除此之外,我还有与 mongo 数据库通信的域服务,并检查用户名是否存在,如果不存在,则将其放在那里。 例如 registerUsername(username) -> true / false 是否注册了
我的问题是,在将处理 CreateUser 命令的用户聚合之上创建命令处理程序是否是个好主意,无论它是否具有用户名都会正确调度 commands/events?像这样:
@Component
class UserCommandHandler(
@Autowired
private val repository: Repository<User>,
@Autowired
private val eventBus: EventBus,
@Autowired
private val service: UniqueUserService
) {
@CommandHandler
fun createUser(cmd: CreateUser) {
if (this.service.registerUsername(cmd.username)) {
this.repository.newInstance { User(cmd.id) }
.handle(GenericCommandMessage(cmd))
} else {
this.eventBus.publishEvent(UserCreateFailed(cmd.id, cmd.username))
}
}
}
这个问题不一定与 ddd 中的集合唯一性有关,但更多的是一个问题,我应该在哪里放置域服务的依赖项?我可能可以创建用户注册 saga 并将该服务注入 saga 但我认为 saga 应该只依赖于命令调度并且没有任何 if/else 逻辑。
我认为放置域服务的位置取决于手头的用例。 我通常尝试让域服务完全不对其他服务或数据库进行虚拟出站调用。
您现在设想的域服务正是这样做的,就像您指出的那样,解决了唯一性问题。 在这种情况下,您可能会采用建议的方法。
您还可以考虑引入一个 MessageHandlerInterceptor
(或者更高级的 HandlerEnhancerDefinition
,如 here 所述),专门触发创建命令并执行所需的检查。
如果它是像我刚才描述的那样的域服务(例如来自域服务的零出站调用),那么您可以安全地将它连接到您的命令处理函数中以执行某些操作。
如果您处于 Spring 环境中,只需将您的域服务作为一个 bean 并将其作为参数提供给您的消息处理函数就足以让 Axon 为您解决它(通过ParameterResolvers
,如 here 所述)。
希望这对您有所帮助@PolishCivil!