master
1export class Resolver {
2 constructor(factory) {
3 this.factory = factory;
4 }
5
6 resolveWith(container) {
7 if (this.isConstructor()) {
8 return this.resolveDependenciesUsing(container);
9 }
10 else {
11 return this.factory(container);
12 }
13 }
14
15 parseConstructor(func) {
16 const code = func.toString();
17 const regex = /function ([a-zA-Z]*)\((.*)\) *\{/;
18 return code.match(regex);
19 }
20
21 isConstructor() {
22 return this.factory.name;
23 //return this.parseConstructor(this.factory)[1] != '';
24 }
25
26 resolveDependenciesUsing(container) {
27 const ctor = this.parseConstructor(this.factory);
28 const parameters = ctor.slice(2)[0].split(',').filter(Boolean);
29 const dependencies = parameters.map((parameter) => {
30 return container.resolve(parameter.trim());
31 });
32 return new this.factory(...dependencies);
33 }
34}
35
36export class Registration {
37 constructor(factory) {
38 this.factory = factory;
39 }
40
41 create(container) {
42 return new Resolver(this.factory).resolveWith(container);
43 }
44
45 asSingleton() {
46 const originalFactory = this.factory;
47 let item = null;
48 this.factory = (container) => {
49 if (item == null) {
50 item = new Resolver(originalFactory).resolveWith(container);
51 }
52 return item;
53 };
54 }
55}
56
57export default class Registry {
58 constructor() {
59 this.registrations = new Map();
60 }
61
62 register(key, factory) {
63 if (!this.isRegistered(key)) {
64 this.registrations.set(key, new Set());
65 }
66 const registration = new Registration(factory);
67 this.registrations.get(key).add(registration);
68 return registration;
69 }
70
71 isRegistered(key) {
72 return this.registrations.has(key);
73 }
74
75 resolve(key) {
76 if (!this.isRegistered(key)) {
77 throw `"${key}" is not registered`;
78 }
79
80 try {
81 const registration = this._registrationsFor(key)[0];
82 return registration.create(this);
83 } catch(error) {
84 console.error(`ERROR: Could not resolve "${key}" ${error}`);
85 throw error;
86 }
87 }
88
89 resolveAll(key) {
90 return this._registrationsFor(key).map(registration => registration.create(this));
91 }
92
93 _registrationsFor(key) {
94 return Array.from(this.registrations.get(key));
95 }
96}