UNPKG

vv-di

Version:

Simple IoC Container

163 lines (139 loc) 3.18 kB
/** * * @type {Promise|bluebird} */ var Promise = require('bluebird'); /** * @name Container * @constructor */ var Container = function () { this.singletons = {}; this.bindings = {}; this.asyncs = []; }; /** * Binds a dependency with given factory * * @param {string} alias * @param {Container~FactoryCallback} factory */ Container.prototype.bind = function (alias, factory) { this.bindings[alias] = factory; }; /** * Instantiate a dependency * * @param alias * @returns {*} */ Container.prototype.make = function (alias) { if (!this.bindings.hasOwnProperty(alias)) { throw new Error('Could not instantiate [' + alias + ']'); } var factory = this.bindings[alias]; if (!this.singletons.hasOwnProperty(alias)) { return factory.apply(factory, [this]); } if(!this.singletons[alias]) { this.singletons[alias] = true; this.bindings[alias] = factory.apply(factory, [this]); } return this.bindings[alias]; }; /** * Binds a dependency as singleton (sharedService) * * @param {string} alias * @param {Container~FactoryCallback} factory */ Container.prototype.singleton = function (alias, factory) { this.bindings[alias] = factory; this.singletons[alias] = false; }; /** * * @param {string} alias * @param {Container~AsyncFactoryCallback} asyncFactory */ Container.prototype.bindAsync = function (alias, asyncFactory) { var self = this; this.asyncs.push(new Promise(function (resolve, reject) { asyncFactory(self, { done: function (result) { self.singleton(alias, function () { return result; }); resolve(); }, error: reject}); } )); }; Container.prototype.boot = function () { var self = this; return Promise.all(this.asyncs).then(function () { return self; }); }; /** * Register a service provider * * @param {Container~ServiceProviderInterface} serviceProvider */ Container.prototype.use = function (serviceProvider) { serviceProvider.register(this); }; /** * Load and register service provider * * @param {string} serviceProviderLocation */ Container.prototype.load = function (serviceProviderLocation) { this.use(require(this.root + "/" + serviceProviderLocation)); }; /** * * @param {string} root */ Container.prototype.setRoot = function (root) { this.root = root; return this; }; module.exports = Container; /** * * @type {Container} */ var singletonContainer = null; /** * * @returns {Container} */ module.exports.instance = function () { if (!singletonContainer) { singletonContainer = new Container(); } return singletonContainer; }; /** * @callback * @name Container~FactoryCallback * @param {Container=} container * @return {*} */ /** * @callback * @name Container~AsyncFactoryCallback * @param {Container} container * @param {{done, error}} call */ /** * @interface * @name Container~ServiceProviderInterface */ /** * @method * @name Container~ServiceProviderInterface#register * @param {Container} container */