Just for learning purpose I thought to write a simple and useful dependency injection service which would just do dependency injection but also it should expose its core too which would let the client code to do some advance stuffs.
I took inspiration from here but I think it does too much apart from that I think that the Factory and Provider thing can be done via calling resolve method in my library.
I need to know if I am missing something or can I improve my code to handle more cases which I don't know yet.
const RE = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
const Color = {
RED: 'RED',
GREEN: 'GREEN',
BLUE: 'BLUE',
};
class Door {
constructor(color) {
this.color = color;
}
open() {
console.log('Kitchen door is open now!');
}
}
class Stove {
constructor() {
}
on() {
console.log('Gas stove is turned on!');
}
off() {
console.log('Gas stove is now off!');
}
}
class TeaMaker {
constructor(door, stove) {
this.door = door;
this.stove = stove;
}
makeTea() {
this.door.open();
this.stove.on();
console.log('Put water on stop');
this.stove.off();
console.log('Enjoying tea :)');
}
}
const injector = {
dependencies: {},
register: (key, value) => {
injector.dependencies[key] = value;
},
resolve: (deps, fn, scope={}) => {
let args = [];
for (let d of deps) {
if (injector.dependencies[d]) {
args.push(injector.dependencies[d]);
} else {
throw new Error(`Unkown Dep: ${d}`);
}
}
return () => {
return fn.call(scope, ...args, ...arguments);
};
},
get: (fn) => {
let deps = fn.toString().match(RE)[1].replace(/ /g, '').split(',');
let args = [];
for (let d of deps) {
if (injector.dependencies[d]) {
args.push(injector.dependencies[d]);
} else {
throw new Error(`Unkown Dep: ${d}`);
}
}
return new fn(...args);
}
};
injector.register('door', new Door(Color.RED));
injector.register('stove', new Stove());
let makeTea = injector.resolve(['door', 'stove'], function(door, stove) {
door.open();
stove.on();
console.log('Put water on stop');
stove.off();
console.log('Enjoying tea :)');
});
makeTea();
let teaMaker = injector.get(TeaMaker);
teaMaker.makeTea();
Output:
Kitchen door is open now!
Gas stove is turned on!
Put water on stop
Gas stove is now off!
Enjoying tea :)
Kitchen door is open now!
Gas stove is turned on!
Put water on stop
Gas stove is now off!
Enjoying tea :)