Skip to content

Instantly share code, notes, and snippets.

@sweikenb
Created July 17, 2018 12:13
Show Gist options
  • Save sweikenb/dd24b8d59237405392f843d40fa707fa to your computer and use it in GitHub Desktop.
Save sweikenb/dd24b8d59237405392f843d40fa707fa to your computer and use it in GitHub Desktop.
/**
* Creates the container instance
*
* @param {Object|null} params
* @constructor
*/
var Dicon = function (params) {
this.params = {};
this.services = {};
this.container = {};
this.autoloader = {};
if (params) {
this.setParameters(params);
}
};
/**
* Registers an parameter for value dependencies
*
* @param {String} name
* @param {*} value
* @returns {Dicon}
*/
Dicon.prototype.setParameter = function (name, value) {
this.params['%' + name + '%'] = value;
return this;
};
/**
* Registers multiple parameters for value dependencies
*
* @param {Object} params
* @returns {Dicon}
*/
Dicon.prototype.setParameters = function (params) {
var index;
for (index in params) {
if (params.hasOwnProperty(index)) {
this.setParameter(index, params[index]);
}
}
return this;
};
/**
* Returns the requested parameter value or null
*
* @param {String} name
* @returns {*}
*/
Dicon.prototype.getParameter = function (name) {
return (this.params['%' + name + '%'] || null);
};
/**
* Registers the given service with the specified service-id and its optional dependencies.
*
* @param {String} id
* @param {Object} klass
* @param {Array|null} deps
* @returns {Dicon}
*/
Dicon.prototype.register = function (id, klass, deps) {
if (typeof this.services[id] !== 'undefined') {
throw "Service '" + id + "' already registered!";
}
this.services[id] = [klass, (deps || [])];
return this;
};
/**
* Returns the requested service instance, by default as singleton.
*
* @param {String} id
* @param {boolean|null} noSingleton
* @returns {*}
*/
Dicon.prototype.get = function (id, noSingleton) {
if ('&' === id) {
return this;
}
if (noSingleton) {
return this._resolve(id, true);
}
if (typeof this.container[id] === 'undefined') {
this.container[id] = this._resolve(id, false);
}
return this.container[id];
};
/**
* Resolves the desired service (by default as singleton) and calls the optional callback with
* the required service as first parameter and the container as second parameter.
*
* @param {String} id
* @param {Function|null} callback
* @param {boolean|null} noSingleton
* @return {Dicon}
*/
Dicon.prototype.run = function (id, callback, noSingleton) {
var service = this.get(id, noSingleton);
if (typeof callback === 'function') {
callback.apply(null, [service, this]);
}
return this;
};
/**
* Internal method for dependency-resolving. Don't use this directly!
*
* @param {String} id
* @param {boolean|null} noSingleton
* @returns {*}
* @private
*/
Dicon.prototype._resolve = function (id, noSingleton) {
if (typeof this.services[id] === 'undefined') {
throw "Unknown service '" + id + "' requested.";
}
var
klass = this.services[id][0],
deps = this.services[id][1],
count = deps.length,
args = [];
for (var i = 0; i < count; i++) {
var
dep = deps[i],
param = this.params[dep];
if (typeof param !== 'undefined') {
args.push(param);
} else {
args.push(this.get(dep, noSingleton));
}
}
return this._new(klass, args);
};
/**
* Internal helper method to create new instances of classes.
*
* @param {Object} klass
* @param {Array} deps
* @returns {*}
* @private
*/
Dicon.prototype._new = function (klass, deps) {
function F(args) {
return klass.apply(this, args);
}
F.prototype = klass.prototype;
return new F(deps);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment