Simple no nonsense dependency injection for extensibility and testability
Install from NPM
Help with development on GitHub
Donations accepted. 😃 😃 😃 $5 $5 😘 😘 😘
Note: Uses ES6/ES2015 features and may fail on Node versions prior to v6.
const pluginjector = require('pluginjector')
const inject = pluginjector(myModule)
const myNewModule = inject(myPlugin)
const myModule = { val: 1 }
const myPlugin = { val: 2 }
const newModule = pluginjector(MyModule)(myPlugin)
assert(newModule.val === 2) // true
const myModule = {
method (){return 'method'}
}
const myPlugin = {
method (){return ('plugin')}
}
const newModule = pluginjector(MyModule)(myPlugin)
assert(newModule.method() === 'plugin') // true
const myPlugin {
method( return 'method' )
}
const myNewModule = inject({pluginname: myPlugin})
assert(myNewModule.myPlugin.method() === 'method') // true
more detailed look at this later
const myModule = {val: 1}
const myPlugin = {
pluginjectorBindThis: true,
method (){ return this.val }
}
const newModule = pluginjector(myModule)({myPlugin})
assert(newModule.myPlugin.method() === 1) // true
const newModule = inject('../path/to/my/file')
const newNamespacedModule = inject({pluginName: '../path/to/my/file'})
// filenames are automatically namespaced in camelCase
const nModule = inject('../location/my-plugin')
assert( !!nModule.myPlugin ) // true
const inject = (myModule, {dir: '../path/to/default/directory'})
const newModule = inject('pluginName')
const newNamespacedModule = inject({differentPluginName: 'pluginName'})
const inject = pluginjector(myModule)
const newModule = inject({data: 'abc'})
inject({moreData: 'def'})
assert(newModule.data + newModule.moreData === 'abcdef') // true
let inject = plugininjector({data: 'core module'})
const newModule = inject({data: 'new module'})
inject = pluginjector(myModule)
const anotherNewModule = inject({})
assert(newModule.data === 'new module') // true
assert(anotherNewModule.data === 'core module') // true
const inject = pluginjectore(coreModule, {proto: true})
const newModule = inject(plugin)
assert(coreModule.isPrototypeOf(newModule)) // true
const myModule = { val: 1 }
const myPlugin = {
// `this` will naturally point to parent module for first layer
// of methods unless you namespace it
method(){ return this.val }
obj1: {
// all methods here will get `this` bound to parent module
pluginjectorBindThis: true, // flag, any truthy value
method(){ return this.val },
method2(){ return this.obj2.val }
},
obj2: {
// no flag, so these will not get special binding
val:2,
method: ()=>{ return this.val }
},
obj3: {
// falsey flag doesn't count
pluginjectorBindThis: false,
val:3,
method: ()=>{ return this.val }
}
}
let newModule = require('pluginjector')(myModule)(myPlugin)
assert(newModule.method() === 1) // true
assert(newModule.obj1.method() === 1) // true
assert(newModule.obj1.method2() === 2) // true
assert(newModule.obj2.method() === 2) // true
assert(newModule.obj3.method() === 3) // true
// with namespace,but no flag, `this` points to `newModule.plugin`
newModule = require('pluginjector')(myModule)({plugin: myPlugin})
assert(newModule.plugin.method() === 1) // false, `this.val` does not exist