在AxonIQ中放置域服务的位置

在AxonIQ中放置域服务的位置,axon,Axon,我有一个用户聚合,它是使用CreateUser命令创建的,该命令由聚合标识符和用户名组成 除此之外,我还有一个域服务,它与MongoDB进行通信,并检查用户名是否存在,如果不存在,则将其放在那个里。 例如registerUsername(username)->true/false,无论它是否注册了它 我的问题是,在处理CreateUser命令的用户聚合上创建命令处理程序是不是一个好主意?它是否有用户名,是否会发送正确的命令/事件?像这样: @Component class UserCommand

我有一个用户聚合,它是使用CreateUser命令创建的,该命令由聚合标识符和用户名组成

除此之外,我还有一个域服务,它与MongoDB进行通信,并检查用户名是否存在,如果不存在,则将其放在那个里。 例如registerUsername(username)->true/false,无论它是否注册了它

我的问题是,在处理CreateUser命令的用户聚合上创建命令处理程序是不是一个好主意?它是否有用户名,是否会发送正确的命令/事件?像这样:

@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))
    }
}
}
@组件
类UserCommandHandler(
@自动连线
专用val存储库:存储库,
@自动连线
私有val事件总线:事件总线,
@自动连线
专用val服务:UniqueUserService
) {
@命令处理程序
趣味createUser(cmd:createUser){
if(this.service.registerUsername(cmd.username)){
this.repository.newInstance{User(cmd.id)}
.handle(GenericCommandMessage(cmd))
}否则{
this.eventBus.publishEvent(UserCreateFailed(cmd.id,cmd.username))
}
}
}

这个问题不一定与ddd中的集合唯一性有关,但更重要的是,我应该将域服务的依赖性放在哪里?我可能会创建用户注册saga并将该服务注入saga中,但我认为saga应该只依赖于命令调度,而没有任何if/else逻辑。

我认为放置域服务的位置取决于手头的用例。 我通常会尝试让域服务执行虚拟操作,而不会对其他服务或数据库进行任何出站调用

然而,正如您所指出的,您现在构思的域服务正是为了解决唯一性问题。 在这种情况下,您可能会使用建议的方法

您还可以考虑引入一个
messagehandler拦截器
(或者更高级的
HandlerEnhancerDefinition
),特别是在create命令上触发并执行所需的检查

如果它是我刚才描述的域服务(例如,域服务的出站调用为零),那么您可以在命令处理函数中安全地连接它以执行某些操作

如果您在Spring环境中,只需将域服务作为bean并将其作为参数提供给消息处理函数,Axon就足以为您解析它(通过
ParameterResolvers
,如前所述)

希望这对你有所帮助@PolishCivil