代码之家  ›  专栏  ›  技术社区  ›  Ming

事件来源:命令总线

  •  0
  • Ming  · 技术社区  · 4 年前

    你好,我正在做一个命令总线来使用类似的东西:

    commandbus.execute(新命令(commandDTO))

    但我不想用装饰器来做这件事,所以我想到了以下几点:

    命令:

    export interface ICommandHandler<
      TCommand extends ICommand = any,
      TResult = any
    > {
      execute(command: TCommand): Promise<TResult>;
    }
    export interface ICommandPublisher<CommandBase extends ICommand = ICommand> {
      publish<T extends CommandBase = CommandBase>(command: T): any;
    }
        export interface ICommand {}
    

    命令总线:

    export interface ICommandBus<CommandBase extends ICommand = ICommand> {
      execute<T extends CommandBase>(command: T): Promise<any>;
        register(command:ICommand, handlers: readonly ICommandHandler[]): void;
    }
    
    export class CommandBus {
    execute<T extends CommandBase>(command: T): Promise<any> {
        const commandName = this.getCommandName(command as any);
        const handler = this.handlers.get(commandName);
        if (!handler) throw new CommandHandlerNotFoundException(commandName);
        this.subject$.next(command);
        return handler.execute(command);
      }
    
      bind<T extends CommandBase>(handler: ICommandHandler<T>, name: string) {
        this.handlers.set(name, handler);
      }
    
      register(command: ICommand, handlers: ICommandHandler<any, any>[]) {
        handlers.forEach((handler) =>
          this.registerHandler(this.getCommandName(command), handler)
        );
      }
    
      protected registerHandler(
        commandName: string,
        handler: ICommandHandler<CommandBase, any>
      ) {
        this.bind(handler, commandName);
      }
    
      private getCommandName(command: ICommand): string {
        const { constructor } = Object.getPrototypeOf(command);
        return constructor.name as string;
      }
    }
    export class ObservableBus<T> extends Observable<T> {
      protected _subject$ = new Subject<T>();
    
      constructor() {
        super();
        this.source = this._subject$;
      }
    
      public get subject$() {
        return this._subject$;
      }
    }
    

    但这似乎不是一件愉快的事情,也就是说,我必须以一种怪诞的方式在命令总线上注册:

    寄存器(〔{commandA,事件A},{commandb,事件b}〕)

    我想知道是否有人可以帮助我通过读取文件夹并从文件中获取默认值来普及commandbus,

    我应该通过链接到每个命令名在每个事件中添加一个属性吗?

    或者在每个命令文件中添加一个要调用的事件名称?

    0 回复  |  直到 4 年前