@loke/di-ioc
Advanced tools
Comparing version 2.0.3 to 2.1.0
@@ -8,3 +8,9 @@ 'use strict'; | ||
const { applyNew, ensureCanLoad, singletonGetter } = require('./utils'); | ||
const { TYPE_SINGLETON, TYPE_TRANSIENT, TYPE_INTERFACE, TYPE_SUBROUTER } = require('./types'); | ||
const { | ||
TYPE_SINGLETON, | ||
TYPE_TRANSIENT, | ||
TYPE_INTERFACE, | ||
TYPE_SUBROUTER, | ||
} = require('./types'); | ||
const { EventEmitter } = require('events'); | ||
@@ -37,2 +43,3 @@ /** | ||
this._defs = []; | ||
this._emitter = new EventEmitter(); | ||
} | ||
@@ -74,3 +81,4 @@ | ||
use(path, fn) { // Subrouter | ||
use(path, fn) { | ||
// Subrouter | ||
return this.set('use', path, fn); | ||
@@ -109,3 +117,5 @@ } | ||
const defs = this._defs.filter(item => (item.name === name && item.type !== TYPE_INTERFACE)); | ||
const defs = this._defs.filter( | ||
(item) => item.name === name && item.type !== TYPE_INTERFACE | ||
); | ||
if (!defs.length) return null; | ||
@@ -132,10 +142,11 @@ return defs[0]; | ||
// Extract dependencies for this factory based on the parameter names | ||
var deps = (typeof factory === 'function') | ||
? annotate(factory) | ||
: []; | ||
var deps = typeof factory === 'function' ? annotate(factory) : []; | ||
// constructed name is stripped of invalid chars, and camelCased | ||
var name = path.replace('./', '').replace(/\.js$/, '').replace(/-(.)/g, function (s, first) { | ||
return first.toUpperCase(); | ||
}); | ||
var name = path | ||
.replace('./', '') | ||
.replace(/\.js$/, '') | ||
.replace(/-(.)/g, function (s, first) { | ||
return first.toUpperCase(); | ||
}); | ||
@@ -160,3 +171,5 @@ // Add the definition | ||
// Allows for dependencies to be replaced (useful for testing) | ||
this._defs = this._defs.filter(item => (item.name !== name || item.type === TYPE_INTERFACE)); | ||
this._defs = this._defs.filter( | ||
(item) => item.name !== name || item.type === TYPE_INTERFACE | ||
); | ||
} | ||
@@ -177,5 +190,3 @@ | ||
const router = nameArr.length | ||
? this.get(nameArr.join('.')).factory | ||
: this; | ||
const router = nameArr.length ? this.get(nameArr.join('.')).factory : this; | ||
@@ -196,9 +207,12 @@ const def = router.get(lName); | ||
const def = deepSearch(this, name); | ||
return def && function (services) { | ||
const args = def.deps.map(function (dep) { | ||
return services[dep]; | ||
}); | ||
const newInstance = {}; | ||
return def.factory.apply(newInstance, args) || newInstance; | ||
}; | ||
return ( | ||
def && | ||
function (services) { | ||
const args = def.deps.map(function (dep) { | ||
return services[dep]; | ||
}); | ||
const newInstance = {}; | ||
return def.factory.apply(newInstance, args) || newInstance; | ||
} | ||
); | ||
} | ||
@@ -210,2 +224,7 @@ | ||
on(event, fn) { | ||
this._emitter.on(event, fn); | ||
return this; | ||
} | ||
/** | ||
@@ -218,5 +237,6 @@ * Builds the container | ||
*/ | ||
_build(getters, prefix) { | ||
_build(getters, prefix, emitter) { | ||
const container = new Container(); | ||
const defs = this._defs; | ||
emitter = emitter || this._emitter; | ||
@@ -228,3 +248,3 @@ defs.forEach((def) => { | ||
const subrouter = def.factory; | ||
const subcontainer = subrouter._build(getters, longName); | ||
const subcontainer = subrouter._build(getters, longName, emitter); | ||
@@ -241,4 +261,6 @@ container.set(def.name, subcontainer); | ||
emitter; | ||
// this function signature is a bit f'd | ||
this._buildService(def, longName, getters, defs, container); | ||
this._buildService(def, longName, getters, defs, container, emitter); | ||
}); | ||
@@ -249,3 +271,3 @@ | ||
_buildService(def, longName, getters, defs, container) { | ||
_buildService(def, longName, getters, defs, container, emitter) { | ||
ensureCanLoad(def, getters, defs, longName); | ||
@@ -258,3 +280,8 @@ | ||
if (existing && !(existing instanceof Interface)) { | ||
throw new Error('Re-definition of service ' + existing.longName.join('.') + ': ' + longName.join('.')); | ||
throw new Error( | ||
'Re-definition of service ' + | ||
existing.longName.join('.') + | ||
': ' + | ||
longName.join('.') | ||
); | ||
} | ||
@@ -280,3 +307,8 @@ | ||
if (getter instanceof Interface) { | ||
throw new Error('Interface ' + getter.longName.join('.') + ' has no implementation, but is required by ' + longName.join('.')); | ||
throw new Error( | ||
'Interface ' + | ||
getter.longName.join('.') + | ||
' has no implementation, but is required by ' + | ||
longName.join('.') | ||
); | ||
} | ||
@@ -289,5 +321,11 @@ | ||
emitter.emit('factory-called', { name: longName.join('.') }); | ||
if (newInstance.stop) { | ||
if (def.type === TYPE_TRANSIENT) { | ||
throw new Error('Service "' + longName.join('.') + '" can\'t have a .stop() method because it is transient.'); | ||
throw new Error( | ||
'Service "' + | ||
longName.join('.') + | ||
'" can\'t have a .stop() method because it is transient.' | ||
); | ||
} | ||
@@ -298,5 +336,28 @@ container.setActive(newInstance); | ||
if (validate && existing.validate(newInstance) === false) { | ||
throw new Error('Service "' + longName.join('.') + '" failed to validate against interface ' + existing.longName.join('.') + '.'); | ||
throw new Error( | ||
'Service "' + | ||
longName.join('.') + | ||
'" failed to validate against interface ' + | ||
existing.longName.join('.') + | ||
'.' | ||
); | ||
} | ||
return newInstance; | ||
if (typeof newInstance !== 'object' || newInstance === null) { | ||
emitter.emit('service-unproxyable', { name: longName.join('.') }); | ||
return newInstance; | ||
} | ||
const accessedProps = new Set(); | ||
return new Proxy(newInstance, { | ||
get: (target, prop) => { | ||
if (!accessedProps.has(prop)) { | ||
accessedProps.add(prop); | ||
emitter.emit('service-used', { name: longName.join('.'), prop }); | ||
} | ||
return Reflect.get(target, prop); | ||
}, | ||
}); | ||
}; | ||
@@ -312,2 +373,4 @@ | ||
container.set(def.name, get); | ||
emitter.emit('factory-added', { name: longName.join('.') }); | ||
} | ||
@@ -346,3 +409,3 @@ | ||
return defn.apply(newInstance, args) || newInstance; | ||
} | ||
}, | ||
}; | ||
@@ -372,3 +435,3 @@ }; | ||
for(var i = 0; i < defs.length; i++) { | ||
for (var i = 0; i < defs.length; i++) { | ||
var def = defs[i]; | ||
@@ -375,0 +438,0 @@ if (def.type === TYPE_INTERFACE) continue; |
{ | ||
"name": "@loke/di-ioc", | ||
"version": "2.0.3", | ||
"version": "2.1.0", | ||
"description": "Node.js dependency injection.", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
Sorry, the diff of this file is not supported yet
18191
442