gpt4 book ai didi

typescript - NestJs CQRS - 与现有的 TypeORM 实体聚合设置

转载 作者:行者123 更新时间:2023-12-01 06:40:45 25 4
gpt4 key购买 nike

所以这里有一个官方的例子
https://github.com/kamilmysliwiec/nest-cqrs-example
我尝试为三个简单的功能创建自己的功能:

  • 获取所有用户
  • 通过 id
  • 获取一个用户
  • 创建用户

  • 我正在使用 TypeORM 并且有一个基本的 User 实体。因此,基于官方示例代码,我创建了一个用于创建用户的命令处理程序( create.user.handler.ts ):
    @CommandHandler(CreateUserCommand)
    export class CreateUserHandler implements ICommandHandler<CreateUserCommand> {
    constructor(
    private readonly usersRepository: UsersRepository,
    private readonly eventPublisher: EventPublisher,
    ) {}

    public async execute(command: CreateUserCommand): Promise<void> {
    const createdUser: User = await this.usersRepository.createUser(
    command.username,
    command.password,
    );

    // const userAggregate: UserAggregate = this.eventPublisher.mergeObjectContext(
    // createdUser,
    // );
    // userAggregate.doSomething(createdUser);
    // userAggregate.commit();
    }
    }
    它所做的只是将一个新的用户实体持久化到数据库中。但是我现在没有得到的是如何处理 User 聚合。合并对象上下文时,我无法传入创建的用户实体。而且我不知道聚合应该处理哪个逻辑。所以基于这个用户聚合( user.model.ts ):
    export class User extends AggregateRoot {
    constructor(private readonly id: string) {
    super();
    }

    public doSomething(user: UserEntity): void {
    // do something here?

    this.apply(new UserCreatedEvent(user));
    }
    }
    我知道我可以引发事件,即创建了一个新用户并将其推送到历史记录中。但这是它唯一负责的事情吗?
    那么我将如何设置用户聚合并正确创建用户处理程序?
    当传入创建的实体时,我收到类似的错误

    Argument of type 'User' is not assignable to parameter of type 'AggregateRoot'. Type 'User' is missing the following properties fromtype 'AggregateRoot': autoCommit, publish, commit, uncommit, and 7more.ts(2345)


    这是有道理的,因为 TypeORM 实体扩展了 BaseEntity并且聚合扩展 AggregateRoot .不幸的是,官方示例没有展示如何处理聚合和数据库实体。
    更新 :删除了指向临时存储库的链接,因为它不再存在。

    最佳答案

    @cojack 的回答假设您的 TypeORM 实体定义和 CQRS AggregateRoot 是由同一个类定义的。许多 NestJS + CQRS 项目都是这样实现的(虽然这不是最佳实践,并且违反了单一职责原则。并且您的域类不应依赖于您的数据库)。
    正如您在评论中所述,如果您的 TypeORM 定义必须从 BaseEntity 扩展,这是有问题的。 ,因为您也不能从 AggregateRoot 扩展.
    但没有要求这样做。在您的命令处理程序中,您可以调用 UsersRepository例如验证具有该名称的用户是否已存在,然后创建该用户。
    然后在您的 mergeObjectContext您可以实例化在单独的类中定义的聚合根实体,并从您刚刚创建的 User 实体中传递适当的信息。
    这方面的一个例子可以在 nestjs-rest-cqrs-example 中找到。项目:

    @CommandHandler(CreateAccountCommand)
    export class CreateAccountCommandHandler implements ICommandHandler<CreateAccountCommand> {
    constructor(
    @InjectRepository(AccountEntity) private readonly repository: AccountRepository,
    private readonly publisher: EventPublisher,
    ) {}

    async execute(command: CreateAccountCommand): Promise<void> {
    // Validation of the command (check if account with this email already exists).
    await this.repository.findOne({ where: [{ email: command.email }]}).then((item) => {
    if (item) throw new HttpException('Conflict', HttpStatus.CONFLICT);
    });

    const { name, email, password } = command;
    // Create the account via the repository. The TypeORM entity is returned.
    const result = await this.repository.save(new CreateAccountMapper(name, email, bcrypt.hashSync(password)));

    const account: Account = this.publisher.mergeObjectContext(
    // Create the AggregateRoot entity to be passed to the context.
    new Account(result.id, name, email, result.password, result.active),
    );
    account.commit();
    }
    }
    这个项目在聚合根中的事件方面做得并不多,但我希望你明白了。
    有很多方法可以布置 CQRS 模型和添加逻辑的位置。有关更复杂但布局合理的示例,请参见例如 Daruma Backend通过阿德里安洛佩兹。

    关于typescript - NestJs CQRS - 与现有的 TypeORM 实体聚合设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59703497/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com