Created
July 17, 2018 12:13
-
-
Save sweikenb/dd24b8d59237405392f843d40fa707fa to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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