收集修饰的类(没有注册表类)

时间:2018-06-12 15:25:55

标签: typescript

我有一个事件调度程序类,它应该在某些事件中触发侦听器。我想通过装饰器注册事件监听器 - 这已经有效,但我对目前的解决方案并不是100%满意。

目前正在收集事件监听器"由全球注册机构和后来在事件调度员注册。在代码中说我的(简化)装饰器看起来像:

// Decorator
export const EventListener = (events: string[]) => {
  return (target: Type<object>): void => {
    EventListenerRegistry.set(target);
  };
};

// Listener example
@EventListener(['start'])
class OnStart {
  public handle() {
  }
}

调度OnStart事件后,start侦听器就会被触发。

我不喜欢这种方法,需要EventListenerRegistry看起来像:

export const EventListenerRegistry = (new class {
    protected listeners = [];

    public set(target) {
        this.listeners.push(target);
    }
});

导入EventListenerRegistry意味着在任何时候导入相同的实例,使其变得非常漂亮&#34;单身&#39; ish&#34;。

我的听众require通过glob - 所以这种方法可以自动将我的听众注册给我的调度员,而无需做任何额外的工作。

但除了使用(丑陋的)注册表类之外还有其他可能吗?

1 个答案:

答案 0 :(得分:0)

我会使用IoC容器。 Inversify是TypeScript的一个不错的选择。 这将允许这样的事情:

import { injectable, inject } from 'inversify';

enum EventType {
  Start,
}

interface IEvent {
  type: Event;
  handle(): void;
}

@injectable()
class OnStart implements IEvent {
  public readonly type = EventType.Start;
  public handle() {
  }
}

@injectable()
class Application {
  public constructor(@multiInject(EVENT) public events: IEvent[]) {
  }
}

但这确实意味着您必须自己进行绑定:

export const EVENT = symbol('event');
container.bind<IEvent>(EVENT).to(OnStart);
...

但是,如果您真的想让事件自动注册,我想您可以将容器导入装饰器中并在那里进行绑定。

相关问题