我有一个事件调度程序类,它应该在某些事件中触发侦听器。我想通过装饰器注册事件监听器 - 这已经有效,但我对目前的解决方案并不是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
- 所以这种方法可以自动将我的听众注册给我的调度员,而无需做任何额外的工作。
但除了使用(丑陋的)注册表类之外还有其他可能吗?
答案 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);
...
但是,如果您真的想让事件自动注册,我想您可以将容器导入装饰器中并在那里进行绑定。