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}