Skip to content

Commit 6b96379

Browse files
committed
A bit of refactor and better types
Created the DomainEventClass to reflect that each DomainEvent constructor has that type. To do that DomainEvent has been extended with the static properties that will be accesed in each DomainEvent class.
1 parent 898c0ae commit 6b96379

File tree

7 files changed

+40
-18
lines changed

7 files changed

+40
-18
lines changed

src/Contexts/Mooc/CoursesCounter/application/Increment/IncrementCoursesCounterOnCourseCreated.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { DomainEventClass } from '../../../../Shared/domain/DomainEvent';
12
import { DomainEventSubscriber } from '../../../../Shared/domain/DomainEventSubscriber';
23
import { CourseCreatedDomainEvent } from '../../../Courses/domain/CourseCreatedDomainEvent';
34
import { CourseId } from '../../../Shared/domain/Courses/CourseId';
@@ -6,7 +7,7 @@ import { CoursesCounterIncrementer } from './CoursesCounterIncrementer';
67
export class IncrementCoursesCounterOnCourseCreated implements DomainEventSubscriber<CourseCreatedDomainEvent> {
78
constructor(private incrementer: CoursesCounterIncrementer) {}
89

9-
subscribedTo(): any[] {
10+
subscribedTo(): DomainEventClass[] {
1011
return [CourseCreatedDomainEvent];
1112
}
1213

src/Contexts/Shared/domain/DomainEvent.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { Uuid } from './value-object/Uuid';
22

33
export abstract class DomainEvent {
4+
static EVENT_NAME: string;
5+
static fromPrimitives: (...args: any[]) => any;
46
readonly aggregateId: string;
57
readonly eventId: string;
68
readonly occurredOn: Date;
@@ -15,3 +17,5 @@ export abstract class DomainEvent {
1517

1618
abstract toPrimitive(): Object;
1719
}
20+
21+
export type DomainEventClass = Partial<typeof DomainEvent>;
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { DomainEvent } from './DomainEvent';
1+
import { DomainEvent, DomainEventClass } from './DomainEvent';
22

33
export interface DomainEventSubscriber<T extends DomainEvent> {
4-
subscribedTo(): Array<any>;
4+
subscribedTo(): Array<DomainEventClass>;
55

66
on(domainEvent: T): Promise<void>;
77
}

src/Contexts/Shared/infrastructure/EventBus/DomainEventJsonDeserializer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export class DomainEventJsonDeserializer {
1717
throw new Error(`The event ${eventName} doesn't exist or has no subscribers`);
1818
}
1919

20-
return eventClass.fromPrimitives(
20+
return eventClass.fromPrimitives!(
2121
eventData.attributes.id,
2222
eventData.attributes,
2323
eventData.id,
Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,36 @@
1+
import { DomainEventClass } from '../../domain/DomainEvent';
12
import { DomainEventSubscriber } from '../../domain/DomainEventSubscriber';
23

4+
type Mapping = Map<string, DomainEventClass>;
5+
36
export class DomainEventMapping {
4-
mapping: any;
5-
6-
constructor(mapping: any) {
7-
this.mapping = mapping.reduce((prev: any, subscriber: DomainEventSubscriber<any>) => {
8-
subscriber.subscribedTo().forEach(event => {
9-
prev[event.EVENT_NAME] = event;
10-
});
11-
return prev;
12-
}, {});
7+
mapping: Mapping;
8+
9+
constructor(mapping: DomainEventSubscriber<any>[]) {
10+
this.mapping = mapping.reduce(this.eventsExtractor(), new Map<string, DomainEventClass>());
11+
}
12+
13+
private eventsExtractor() {
14+
return (map: Mapping, subscriber: DomainEventSubscriber<any>) => {
15+
subscriber.subscribedTo().forEach(this.eventNameExtractor(map));
16+
return map;
17+
};
1318
}
1419

15-
for(name: string) {
16-
if (!this.mapping[name]) {
20+
private eventNameExtractor(map: Mapping): (domainEvent: DomainEventClass) => void {
21+
return domainEvent => {
22+
const eventName = domainEvent.EVENT_NAME!;
23+
map.set(eventName, domainEvent);
24+
};
25+
}
26+
27+
for(name: string): DomainEventClass {
28+
const domainEvent = this.mapping.get(name);
29+
30+
if (!domainEvent) {
1731
throw new Error(`The Domain Event Class for ${name} doesn't exists or have no subscribers`);
1832
}
19-
return this.mapping[name];
33+
34+
return domainEvent;
2035
}
2136
}

src/Contexts/Shared/infrastructure/EventBus/EventEmitterBus.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export class EventEmitterBus extends EventEmitter {
1717

1818
private registerSubscriber(subscriber: DomainEventSubscriber<DomainEvent>) {
1919
subscriber.subscribedTo().map(event => {
20-
this.on(event.EVENT_NAME, subscriber.on);
20+
this.on(event.EVENT_NAME!, subscriber.on);
2121
});
2222
}
2323

src/Contexts/Shared/infrastructure/EventBus/InMemorySyncEventBus.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ export class InMemorySyncEventBus implements EventBus {
2727
}
2828

2929
addSubscribers(subscribers: Array<DomainEventSubscriber<DomainEvent>>) {
30-
subscribers.map(subscriber => subscriber.subscribedTo().map(event => this.subscribe(event.EVENT_NAME, subscriber)));
30+
subscribers.map(subscriber =>
31+
subscriber.subscribedTo().map(event => this.subscribe(event.EVENT_NAME!, subscriber))
32+
);
3133
}
3234

3335
private subscribe(topic: string, subscriber: DomainEventSubscriber<DomainEvent>): void {

0 commit comments

Comments
 (0)