dependency-injector-container
Advanced tools
Comparing version 1.0.1 to 1.1.0
@@ -5,3 +5,3 @@ { | ||
"description": "Tiny library which does dependency injection. Basically same pattern like in AngularJS.", | ||
"version": "1.0.1", | ||
"version": "1.1.0", | ||
"url": "https://github.com/ayecue/DependencyInjectorContainer#readme" | ||
@@ -31,3 +31,3 @@ }, | ||
"file": "main.js", | ||
"line": 21, | ||
"line": 29, | ||
"description": "Dependency injector container like in AngualarJS.", | ||
@@ -50,3 +50,31 @@ "is_constructor": 1, | ||
"file": "main.js", | ||
"line": 33, | ||
"line": 47, | ||
"description": "Assert helper.", | ||
"itemtype": "method", | ||
"name": "assert", | ||
"access": "private", | ||
"tagname": "", | ||
"params": [ | ||
{ | ||
"name": "condition", | ||
"description": "", | ||
"type": "Boolean" | ||
}, | ||
{ | ||
"name": "message", | ||
"description": "", | ||
"type": "String" | ||
}, | ||
{ | ||
"name": "type", | ||
"description": "", | ||
"type": "Mixed", | ||
"optional": true | ||
} | ||
], | ||
"class": "DependencyInjectorContainer" | ||
}, | ||
{ | ||
"file": "main.js", | ||
"line": 62, | ||
"description": "Set namespace in scope. Module will be instantly available.", | ||
@@ -78,3 +106,3 @@ "itemtype": "method", | ||
"file": "main.js", | ||
"line": 56, | ||
"line": 84, | ||
"description": "Extend namespace to scope. Will be injected as soon as load is called.", | ||
@@ -106,4 +134,4 @@ "itemtype": "method", | ||
"file": "main.js", | ||
"line": 78, | ||
"description": "Receive module.", | ||
"line": 108, | ||
"description": "Receive module. Will automatically initialize module with all it dependencies if it's not already loaded.", | ||
"itemtype": "method", | ||
@@ -126,3 +154,51 @@ "name": "get", | ||
"file": "main.js", | ||
"line": 97, | ||
"line": 126, | ||
"description": "Evaluate defenition.", | ||
"itemtype": "method", | ||
"name": "evalDefinition", | ||
"access": "private", | ||
"tagname": "", | ||
"params": [ | ||
{ | ||
"name": "namespace", | ||
"description": "Module namespace.", | ||
"type": "String" | ||
} | ||
], | ||
"return": { | ||
"description": "", | ||
"type": "Object" | ||
}, | ||
"class": "DependencyInjectorContainer" | ||
}, | ||
{ | ||
"file": "main.js", | ||
"line": 166, | ||
"description": "Load one defenition with all it dependencies. (Use this if you just want to load certain modules and not all)\nIf you want to load via namespace use .get instead.", | ||
"itemtype": "method", | ||
"name": "loadDefinition", | ||
"access": "private", | ||
"tagname": "", | ||
"params": [ | ||
{ | ||
"name": "definition", | ||
"description": "Definition block.", | ||
"type": "Function" | ||
}, | ||
{ | ||
"name": "excludes", | ||
"description": "Modules to exclude from load.", | ||
"type": "Array", | ||
"optional": true | ||
} | ||
], | ||
"return": { | ||
"description": "", | ||
"type": "Object" | ||
}, | ||
"class": "DependencyInjectorContainer" | ||
}, | ||
{ | ||
"file": "main.js", | ||
"line": 219, | ||
"description": "Initialize all defenitions.", | ||
@@ -129,0 +205,0 @@ "itemtype": "method", |
339
main.js
@@ -8,8 +8,9 @@ /* | ||
*/ | ||
;(function(name, definition) { | ||
; | ||
(function(name, definition) { | ||
var theModule = definition(); | ||
var hasDefine = typeof define === 'function' && define.amd; | ||
var hasExports = typeof module !== 'undefined' && module.exports; | ||
if (hasDefine){ // AMD Module | ||
if (hasDefine) { // AMD Module | ||
define(theModule); | ||
@@ -22,142 +23,254 @@ } else if (hasExports) { // Node.js Module | ||
})('DependencyInjectorContainer', function() { | ||
/** | ||
* Dependency injector container like in AngualarJS. | ||
* | ||
* @class DependencyInjectorContainer | ||
* @constructor | ||
* @param {Object} scope Scope for namespaces. | ||
* @private | ||
*/ | ||
function DependencyInjectorContainer(scope) { | ||
this.scope = scope || {}; | ||
} | ||
//Error Messages | ||
var NAMESPACE_TYPE_ERROR = 'Unexpected type for namespace. Namespace needs to be a string.'; //Thrown when unexpected namespace type is given | ||
var NAMESPACE_ALREADY_DEFINED = '%n is aready defined.'; //Thrown as soon as someone tries to override a namespace without the overriden flag set to true | ||
var NAMESPACE_NOT_FOUND = '%n not found.'; //Thrown if namespace is not set | ||
var DEFINITION_NOT_INITIALIZED = 'Definition %d is not initialized.'; //Thrown if definition is not initialized | ||
var DEFINITION_CYCLIC_DEPENDENCY = 'Cyclic dependency in %1 and %2.'; //Thrown if there are cyclic dependencies. | ||
/** | ||
* Set namespace in scope. Module will be instantly available. | ||
* Dependency injector container like in AngualarJS. | ||
* | ||
* @method set | ||
* @chainable | ||
* @param {String} namespace Module namespace. | ||
* @param {Object} module Module to set. | ||
* @param {Boolean} [override] Should override namespace if set. | ||
* @class DependencyInjectorContainer | ||
* @constructor | ||
* @param {Object} scope Scope for namespaces. | ||
* @private | ||
*/ | ||
DependencyInjectorContainer.prototype.set = function(namespace, module, override) { | ||
if (typeof namespace !== 'string') { | ||
throw new TypeError('Namespace has to be a string.'); | ||
} | ||
function DependencyInjectorContainer(scope) { | ||
var hasProperty; | ||
if (override !== true && this.scope.hasOwnProperty(namespace) === true) { | ||
throw new Error(namespace + ' is aready defined.'); | ||
} | ||
scope = scope || {}; | ||
this.scope[namespace] = module; | ||
this.set = set; | ||
this.get = get; | ||
this.extend = extend; | ||
this.load = load; | ||
return this; | ||
}; | ||
/** | ||
* Extend namespace to scope. Will be injected as soon as load is called. | ||
* | ||
* @method extend | ||
* @chainable | ||
* @param {String} namespace Module namespace. | ||
* @param {Array} [dependencies] Module dependencies. | ||
* @param {Object} definition Module definition block. | ||
*/ | ||
DependencyInjectorContainer.prototype.extend = function(namespace, dependencies, definition) { | ||
if (typeof dependencies === 'function') { | ||
definition = dependencies; | ||
dependencies = undefined; | ||
/** | ||
* Assert helper. | ||
* | ||
* @method assert | ||
* @private | ||
* @param {Boolean} condition | ||
* @param {String} message | ||
* @param {Mixed} [type] | ||
*/ | ||
function assert(condition, message, type) { | ||
if (condition === false) { | ||
throw new (type || Error)(message); | ||
} | ||
} | ||
definition.__dependencies__ = dependencies || []; | ||
definition.isDefinition = true; | ||
this.set(namespace, definition); | ||
/** | ||
* Set namespace in scope. Module will be instantly available. | ||
* | ||
* @method set | ||
* @chainable | ||
* @param {String} namespace Module namespace. | ||
* @param {Object} module Module to set. | ||
* @param {Boolean} [override] Should override namespace if set. | ||
*/ | ||
function set(namespace, module, override) { | ||
assert(typeof namespace === 'string', NAMESPACE_TYPE_ERROR, TypeError); | ||
assert( | ||
override === true || scope.hasOwnProperty(namespace) === false, | ||
NAMESPACE_ALREADY_DEFINED | ||
.replace('%n', namespace) | ||
); | ||
return this; | ||
}; | ||
scope[namespace] = module; | ||
/** | ||
* Receive module. | ||
* | ||
* @method get | ||
* @param {String} namespace Module namespace. | ||
* @return {Object} | ||
*/ | ||
DependencyInjectorContainer.prototype.get = function(namespace) { | ||
if (typeof namespace !== 'string') { | ||
throw new TypeError('Namespace has to be a string.'); | ||
} | ||
return this; | ||
}; | ||
if (typeof this.scope[namespace] === 'undefined') { | ||
throw new Error(namespace + ' not found.'); | ||
} | ||
/** | ||
* Extend namespace to scope. Will be injected as soon as load is called. | ||
* | ||
* @method extend | ||
* @chainable | ||
* @param {String} namespace Module namespace. | ||
* @param {Array} [dependencies] Module dependencies. | ||
* @param {Object} definition Module definition block. | ||
*/ | ||
function extend(namespace, dependencies, definition) { | ||
if (typeof dependencies === 'function') { | ||
definition = dependencies; | ||
dependencies = undefined; | ||
} | ||
return this.scope[namespace]; | ||
}; | ||
definition.__dependencies__ = dependencies || []; | ||
definition.isDefinition = true; | ||
definition.namespace = namespace; | ||
/** | ||
* Initialize all defenitions. | ||
* | ||
* @method load | ||
* @chainable | ||
*/ | ||
DependencyInjectorContainer.prototype.load = function() { | ||
var namespaces = Object.keys(this.scope).filter(function(namespace){ | ||
return this.get(namespace).isDefinition === true; | ||
}, this); | ||
var sortedNamespaces = []; | ||
var queue = function(collection) { | ||
var result = []; | ||
set(namespace, definition); | ||
collection.forEach(function(namespace){ | ||
var isRequired = namespaces.some(function(m){ | ||
if (m !== namespace && this.get(m).__dependencies__.indexOf(namespace) !== -1) { | ||
if (this.get(namespace).__dependencies__.indexOf(m) !== -1) { | ||
console.error('Cyclic dependency in ' + namespace + ' and ' + m + '.'); | ||
return; | ||
} | ||
return this; | ||
}; | ||
return true; | ||
} | ||
}, this); | ||
/** | ||
* Receive module. Will automatically initialize module with all it dependencies if it's not already loaded. | ||
* | ||
* @method get | ||
* @param {String} namespace Module namespace. | ||
* @return {Object} | ||
*/ | ||
function get(namespace) { | ||
assert(typeof namespace === 'string', NAMESPACE_TYPE_ERROR, TypeError); | ||
assert( | ||
scope.hasOwnProperty(namespace) === true, | ||
NAMESPACE_NOT_FOUND | ||
.replace('%n', namespace) | ||
); | ||
if (isRequired === true) { | ||
result.push(namespace); | ||
} else { | ||
sortedNamespaces.unshift(namespace); | ||
} | ||
}, this); | ||
return loadDefinition(scope[namespace]); | ||
}; | ||
return result; | ||
}.bind(this); | ||
/** | ||
* Evaluate defenition. | ||
* | ||
* @method evalDefinition | ||
* @private | ||
* @param {String} namespace Module namespace. | ||
* @return {Object} | ||
*/ | ||
function evalDefinition(definition) { | ||
var args; | ||
var compiled; | ||
var depDefinition; | ||
while (namespaces.length > 0) { | ||
namespaces = queue(namespaces); | ||
} | ||
if (definition.isDefinition !== true) { | ||
return definition; | ||
} | ||
sortedNamespaces.forEach(function(namespace){ | ||
var definition = this.get(namespace); | ||
var dependencies = definition.__dependencies__; | ||
var args = dependencies.map(function(depNamespace){ | ||
var module = this.get(depNamespace); | ||
args = definition.__dependencies__.map(function(depNamespace) { | ||
depDefinition = get(depNamespace); | ||
if (module.isDefinition === true) { | ||
console.warn('Module ' + depNamespace + ' is not initialized.'); | ||
if (depDefinition.isDefinition === true) { | ||
console.warn( | ||
DEFINITION_NOT_INITIALIZED | ||
.replace('%d', depNamespace) | ||
); | ||
} | ||
return module; | ||
}, this); | ||
return depDefinition; | ||
}); | ||
try { | ||
this.set(namespace, definition.apply(this, args) || {}, true); | ||
compiled = definition.apply(null, args) || {}; | ||
set(definition.namespace, compiled, true); | ||
} catch (e) { | ||
console.error(namespace, e); | ||
console.error(definition.namespace, e); | ||
} | ||
}, this); | ||
return this; | ||
}; | ||
return compiled; | ||
}; | ||
/** | ||
* Load one defenition with all it dependencies. (Use this if you just want to load certain modules and not all) | ||
* If you want to load via namespace use .get instead. | ||
* | ||
* @method loadDefinition | ||
* @private | ||
* @param {Function} definition Definition block. | ||
* @param {Array} [excludes] Modules to exclude from load. | ||
* @return {Object} | ||
*/ | ||
function loadDefinition(definition, excludes) { | ||
var sortedDefinitions = []; | ||
if (definition.isDefinition !== true) { | ||
return definition; | ||
} | ||
excludes = excludes || []; | ||
excludes.push(definition); | ||
definition.__dependencies__.forEach(function(depNamespace) { | ||
var depDefinition = get(depNamespace); | ||
var excluded; | ||
var result; | ||
if (depDefinition.isDefinition !== true) { | ||
return; | ||
} | ||
if (depDefinition.__dependencies__.indexOf(definition.namespace) !== -1) { | ||
console.error( | ||
DEFINITION_CYCLIC_DEPENDENCY | ||
.replace('%1', definition.namespace) | ||
.replace('%2', depDefinition.namespace) | ||
); | ||
return; | ||
} | ||
excluded = excludes.some(function(d) { | ||
return depDefinition.namespace !== d.namespace; | ||
}); | ||
if (excluded === false) { | ||
return; | ||
} | ||
result = loadDefinition(depDefinition, excludes); | ||
sortedDefinitions = sortedDefinitions.concat(result); | ||
}); | ||
return evalDefinition(definition); | ||
}; | ||
/** | ||
* Initialize all defenitions. | ||
* | ||
* @method load | ||
* @chainable | ||
*/ | ||
function load() { | ||
var namespaces = Object.keys(scope).filter(function(namespace) { | ||
return get(namespace).isDefinition === true; | ||
}); | ||
var sortedNamespaces = []; | ||
var queue = function(collection) { | ||
var result = []; | ||
collection.forEach(function(namespace) { | ||
var isRequired = namespaces.some(function(m) { | ||
if (m !== namespace && get(m).__dependencies__.indexOf(namespace) !== -1) { | ||
if (get(namespace).__dependencies__.indexOf(m) !== -1) { | ||
console.error( | ||
DEFINITION_CYCLIC_DEPENDENCY | ||
.replace('%1', namespace) | ||
.replace('%2', m) | ||
); | ||
return; | ||
} | ||
return true; | ||
} | ||
}); | ||
if (isRequired === true) { | ||
result.push(namespace); | ||
} else { | ||
sortedNamespaces.unshift(namespace); | ||
} | ||
}); | ||
return result; | ||
}; | ||
while (namespaces.length > 0) { | ||
namespaces = queue(namespaces); | ||
} | ||
sortedNamespaces.forEach(function(namespace) { | ||
var definition = get(namespace); | ||
evalDefinition(definition); | ||
}); | ||
return this; | ||
}; | ||
} | ||
return DependencyInjectorContainer; | ||
}); |
@@ -1,1 +0,1 @@ | ||
!function(a,b){var c=b(),d="function"==typeof define&&define.amd,e="undefined"!=typeof module&&module.exports;d?define(c):e?module.exports=c:window[a]=c}("DependencyInjectorContainer",function(){function a(a){this.scope=a||{}}return a.prototype.set=function(a,b,c){if("string"!=typeof a)throw new TypeError("Namespace has to be a string.");if(c!==!0&&this.scope.hasOwnProperty(a)===!0)throw new Error(a+" is aready defined.");return this.scope[a]=b,this},a.prototype.extend=function(a,b,c){return"function"==typeof b&&(c=b,b=void 0),c.__dependencies__=b||[],c.isDefinition=!0,this.set(a,c),this},a.prototype.get=function(a){if("string"!=typeof a)throw new TypeError("Namespace has to be a string.");if("undefined"==typeof this.scope[a])throw new Error(a+" not found.");return this.scope[a]},a.prototype.load=function(){for(var a=Object.keys(this.scope).filter(function(a){return this.get(a).isDefinition===!0},this),b=[],c=function(c){var d=[];return c.forEach(function(c){var e=a.some(function(a){if(a!==c&&-1!==this.get(a).__dependencies__.indexOf(c)){if(-1!==this.get(c).__dependencies__.indexOf(a))return;return!0}},this);e===!0?d.push(c):b.unshift(c)},this),d}.bind(this);a.length>0;)a=c(a);return b.forEach(function(a){var b=this.get(a),c=b.__dependencies__,d=c.map(function(a){var b=this.get(a);return b.isDefinition===!0,b},this);try{this.set(a,b.apply(this,d)||{},!0)}catch(e){}},this),this},a}); | ||
!function(a,b){var c=b(),d="function"==typeof define&&define.amd,e="undefined"!=typeof module&&module.exports;d?define(c):e?module.exports=c:window[a]=c}("DependencyInjectorContainer",function(){function a(a){function e(a,b,c){if(a===!1)throw new(c||Error)(b)}function f(d,f,g){return e("string"==typeof d,b,TypeError),e(g===!0||a.hasOwnProperty(d)===!1,c.replace("%n",d)),a[d]=f,this}function g(a,b,c){return"function"==typeof b&&(c=b,b=void 0),c.__dependencies__=b||[],c.isDefinition=!0,c.namespace=a,f(a,c),this}function h(c){return e("string"==typeof c,b,TypeError),e(a.hasOwnProperty(c)===!0,d.replace("%n",c)),j(a[c])}function i(a){var b,c,d;if(a.isDefinition!==!0)return a;b=a.__dependencies__.map(function(a){return d=h(a),d.isDefinition===!0,d});try{c=a.apply(null,b)||{},f(a.namespace,c,!0)}catch(e){}return c}function j(a,b){var c=[];return a.isDefinition!==!0?a:(b=b||[],b.push(a),a.__dependencies__.forEach(function(d){var e,f,g=h(d);g.isDefinition===!0&&-1===g.__dependencies__.indexOf(a.namespace)&&(e=b.some(function(a){return g.namespace!==a.namespace}),e!==!1&&(f=j(g,b),c=c.concat(f)))}),i(a))}function k(){for(var b=Object.keys(a).filter(function(a){return h(a).isDefinition===!0}),c=[],d=function(a){var d=[];return a.forEach(function(a){var e=b.some(function(b){if(b!==a&&-1!==h(b).__dependencies__.indexOf(a)){if(-1!==h(a).__dependencies__.indexOf(b))return;return!0}});e===!0?d.push(a):c.unshift(a)}),d};b.length>0;)b=d(b);return c.forEach(function(a){var b=h(a);i(b)}),this}a=a||{},this.set=f,this.get=h,this.extend=g,this.load=k}var b="Unexpected type for namespace. Namespace needs to be a string.",c="%n is aready defined.",d="%n not found.";return a}); |
{ | ||
"name": "dependency-injector-container", | ||
"version": "1.0.1", | ||
"version": "1.1.0", | ||
"description": "Tiny library which does dependency injection. Basically same pattern like in AngularJS.", | ||
@@ -5,0 +5,0 @@ "main": "main.js", |
@@ -23,3 +23,3 @@ # dependency-injector-container | ||
Imagine you got several modules in different files which depend on each other. You'll somehow need to compile them in the right order otherwise those modules will throw exception. With this tiny library you don't need to care about that anymore. You just need to extend all your modules to the container and then at the end call ```.load()```. | ||
Imagine you got several modules in different files which depend on each other. You'll somehow need to compile them in the right order otherwise those modules will throw exception. With this tiny library you don't need to care about that anymore. You just need to extend all your modules to the container and then at the end call ```.load()```. Also there's the possibility to just call ``.get()`` after all modules are extended. | ||
@@ -30,3 +30,3 @@ The pattern of this library is pretty similar to what's AngularJS is using. | ||
This library got the size of 1.4 KB. | ||
This library got the size of 1.6 KB. | ||
@@ -63,2 +63,32 @@ | ||
Application.load(); | ||
``` | ||
``` | ||
var DependencyInjectorContainer = require('dependency-injector-container'); | ||
var Application = new DependencyInjectorContainer(); | ||
//Testing | ||
Application.extend('test',function(){ | ||
return { | ||
foo: 'bar' | ||
}; | ||
}); | ||
Application.extend('cow',['test','sheep'],function(test,sheep){ | ||
console.log(test.foo, sheep); | ||
return { | ||
lol: 'moo' | ||
}; | ||
}); | ||
Application.extend('sheep',['test'],function(test){ | ||
console.log(test.foo); | ||
return { | ||
legs: 'walk' | ||
}; | ||
}); | ||
Application.get('cow'); | ||
``` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
156712
31
1790
91
1