Skip to content

Instantly share code, notes, and snippets.

@you-think-you-are-special
Last active April 23, 2018 07:49
Show Gist options
  • Save you-think-you-are-special/a26b1eea87259e456cb9eaa45384c56d to your computer and use it in GitHub Desktop.
Save you-think-you-are-special/a26b1eea87259e456cb9eaa45384c56d to your computer and use it in GitHub Desktop.
JavaScript dependency injection container example
function argsList(method) {
method = method.toString();
const fn = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
const cls = /constructor\s*[^\(]*\(\s*([^\)]*)\)/m;
const FN_ARGS = method[0] === 'f' ? fn : cls;
const depsStr = method.match(FN_ARGS);
const deps = (depsStr) ? depsStr[1].trim().split(/[\s,]+/) : [''];
if (deps[0] === '') {
return [];
}
return deps;
}
module.exports = function () {
const dependencies = {};
const factories = {};
const diContainer = {};
diContainer.factory = function (name, factory) {
factories[name] = factory;
};
diContainer.register = function (name, instance) {
dependencies[name] = instance;
};
diContainer.class = (name, ObjectClass) => {
factories[name] = function () {
const args = argsList(ObjectClass)
.map(dependency => diContainer.get(dependency));
return new ObjectClass(...args);
};
};
diContainer.get = function (name) {
if (!dependencies[name]) {
const factory = factories[name];
dependencies[name] = factory && diContainer.inject(factory);
if (!dependencies[name]) {
throw new Error('Cannot find module:', name);
}
}
return dependencies[name];
};
diContainer.inject = function (factory) {
const args = argsList(factory)
.map(function (dependency) {
return diContainer.get(dependency)
});
return factory.apply(null, args);
};
return diContainer;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment