NestJs – CQRS – 寻找将对象作为构造函数参数传递的简单方法(从DTO到命令)

huangapple go评论102阅读模式
英文:

NestJs - CQRS - Looking for a simple way to pass an object as constructor parameters (From a DTO to a command)

问题

以下是您要翻译的部分:

  1. 我想要按照以下方式初始化一个命令:
  2. const command = new CreateProductCommand(payload);
  3. // 在另一个文件中
  4. export class Payload {
  5. public readonly type: string;
  6. public readonly name?: string;
  7. }
  8. 我的命令定义如下:
  9. export class CreateProductTypeACommand {
  10. public readonly name?: string;
  11. }
  12. 我尝试在构造函数中创建一个抽象命令来实现这个:
  13. export class AbstractCommand<T> implements ICommand {
  14. constructor(args: T) {
  15. Object.assign(this, args);
  16. }
  17. }
  18. // 在另一个文件中
  19. export class CreateProductTypeACommand extends AbstractCommand<CreateProductTypeACommand> {
  20. public readonly name?: string;
  21. }
  22. 但这并不起作用:子类的构造函数会覆盖父类的构造函数,`name` 的值被覆盖为 `undefined`。而且对象最终会具有 `type` 字段。
  23. 有什么想法吗?我宁愿不在我的命令类中放入任何样板代码或定义一个 `CreateProductTypeACommandArgs` 类型。
英文:

I would like to initialize a Command as Follows:

  1. const command = new CreateProductCommand(payload);
  2. // In another file
  3. export class Payload {
  4. public readonly type: string;
  5. public readonly name?: string;
  6. }

where my Command is defined like this:

  1. export class CreateProductTypeACommand {
  2. public readonly name?: string;
  3. }

I have tried create an abstract command to do this in the constructor:

  1. export class AbstractCommand&lt;T&gt; implements ICommand {
  2. constructor(args: T) {
  3. Object.assign(this, args);
  4. }
  5. }
  6. // in another file
  7. export class CreateProductTypeACommand extends AbstractCommand&lt;CreateProductTypeACommand&gt; {
  8. public readonly name?: string;
  9. }

But this dosen't work: the child's constructor overrides the parents and the value for name gets overridden by undefined . Also the object ends up having the type field.

Any idea? I would rather not put any boiler plate code in my command classes or define a CreateProductTypeACommandArgs type.

答案1

得分: 1

I had a similar problem and what I ended up doing was using plainToClass from the class-transformer package.

For example

  1. import { ClassConstructor, plainToClass } from "class-transformer";
  2. // A neat utility function to check you supply all class properties
  3. function map<T, V extends T>(cls: ClassConstructor<T>, plain: V): T {
  4. return plainToClass(cls, plain);
  5. }
  6. function doStuff() {
  7. const newProfile = {
  8. description: "my-description",
  9. name: "my-name",
  10. recentLocation: { lat: 1, lon: 2 },
  11. userId: "my-user-id",
  12. };
  13. const command = map(CreateProfileCommand, newProfile);
  14. ...
  15. }
英文:

I had a similar problem and what I ended up doing was using plainToClass from the class-transformer package.

For example

  1. import { ClassConstructor, plainToClass } from &quot;class-transformer&quot;;
  2. // A neat utility function to check you supply all class properties
  3. function map&lt;T, V extends T&gt;(cls: ClassConstructor&lt;T&gt;, plain: V): T {
  4. return plainToClass(cls, plain);
  5. }
  6. function doStuff() {
  7. const newProfile = {
  8. description: &quot;my-description&quot;,
  9. name: &quot;my-name&quot;,
  10. recentLocation: { lat: 1, lon: 2 },
  11. userId: &quot;my-user-id&quot;,
  12. };
  13. const command = map(CreateProfileCommand, newProfile);
  14. ...
  15. }

huangapple
  • 本文由 发表于 2023年4月13日 16:18:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76003191.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定