Presupuestador_web/shared/lib/contexts/common/domain/events/DomainEvents.ts
2024-04-23 17:29:38 +02:00

96 lines
2.7 KiB
TypeScript

import { AggregateRoot, UniqueID } from '../entities';
import { IDomainEvent } from './DomainEventInterface';
export class DomainEvents {
private static handlersMap: { [key: string]: any } = {};
private static markedAggregates: AggregateRoot<any>[] = [];
/**
* @method markAggregateForDispatch
* @static
* @desc Called by aggregate root objects that have created domain
* events to eventually be dispatched when the infrastructure commits
* the unit of work.
*/
public static markAggregateForDispatch(
aggregate: AggregateRoot<any>
): void {
const aggregateFound = !!this.findMarkedAggregateByID(aggregate.id);
if (!aggregateFound) {
this.markedAggregates.push(aggregate);
}
}
private static dispatchAggregateEvents(
aggregate: AggregateRoot<any>
): void {
aggregate.domainEvents.forEach((event: IDomainEvent) =>
this.dispatch(event)
);
}
private static removeAggregateFromMarkedDispatchList(
aggregate: AggregateRoot<any>
): void {
const index = this.markedAggregates.findIndex((a) =>
a.equals(aggregate)
);
this.markedAggregates.splice(index, 1);
}
private static findMarkedAggregateByID(
id: UniqueID
): AggregateRoot<any> | undefined {
let found: AggregateRoot<any> | undefined = undefined;
for (const aggregate of this.markedAggregates) {
if (aggregate.id.equals(id)) {
found = aggregate;
}
}
return found;
}
public static dispatchEventsForAggregate(id: UniqueID): void {
const aggregate = this.findMarkedAggregateByID(id);
if (aggregate) {
this.dispatchAggregateEvents(aggregate);
aggregate.clearEvents();
this.removeAggregateFromMarkedDispatchList(aggregate);
}
}
public static register(
callback: (event: IDomainEvent) => void,
eventClassName: string
): void {
if (!this.handlersMap.hasOwnProperty(eventClassName)) {
this.handlersMap[eventClassName] = [];
}
this.handlersMap[eventClassName].push(callback);
}
public static clearHandlers(): void {
this.handlersMap = {};
}
public static clearMarkedAggregates(): void {
this.markedAggregates = [];
}
private static dispatch(event: IDomainEvent): void {
const eventClassName: string = event.constructor.name;
if (this.handlersMap.hasOwnProperty(eventClassName)) {
const handlers: any[] = this.handlersMap[eventClassName];
for (const handler of handlers) {
handler(event);
}
}
}
}