patternjavascriptMinor
Designing a toy dependency injection library
Viewed 0 times
toydesigningdependencylibraryinjection
Problem
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
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.
``
}
}
return new fn(...args);
}
};
injector.register('door', new Door(Color.RED));
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));
Solution
In your injector you're exposing the dependencies object, in a way that all could access.
You should consider to hide it instead, so people will use just the API as it should be.
This happened because you choose to define your component just with a plain object approach.
If you want to write a lib or an utility, it is better to use one of the module pattern.
For example wrapping your code in a function if you mean to use it within a browser:
Or with the node modules if you use in node:
So you could expose just the API function you want.
This helps the developer to better understand how you design the lib to be used.
You should consider to hide it instead, so people will use just the API as it should be.
This happened because you choose to define your component just with a plain object approach.
If you want to write a lib or an utility, it is better to use one of the module pattern.
For example wrapping your code in a function if you mean to use it within a browser:
!function () {
const dependencies = {};
const injector = {
// my code here
};
return injector;
}()Or with the node modules if you use in node:
const dependencies = {}
const injector = {
// your code here..
}
export default injectorSo you could expose just the API function you want.
This helps the developer to better understand how you design the lib to be used.
Code Snippets
!function () {
const dependencies = {};
const injector = {
// my code here
};
return injector;
}()const dependencies = {}
const injector = {
// your code here..
}
export default injectorContext
StackExchange Code Review Q#148070, answer score: 3
Revisions (0)
No revisions yet.