{"_id":"circuitbox","_rev":"37-402b09a0ac3f7587c3639c4471170b62","name":"circuitbox","description":"A dependency-injection framework for node.js","dist-tags":{"latest":"2.6.0"},"versions":{"1.0.0-alpha.1":{"name":"circuitbox","version":"1.0.0-alpha.1","description":"A dependency-injection framework for node.js","main":"./lib/index.js","homepage":"http://circuitbox.oddjobsman.me","scripts":{"test":"node_modules/.bin/grunt ci"},"engines":{"node":">=0.8"},"repository":{"type":"git","url":"https://github.com/oddjobsman/circuitbox"},"keywords":["ioc","di","dependency injection"],"author":{"name":"oddjobsman","email":"oddjobsman@ranganathkini.com"},"license":"MIT","bugs":{"url":"https://github.com/oddjobsman/circuitbox/issues"},"dependencies":{"async":"~0.2.9","underscore":"~1.5.2","when":"~2.7.0","underscore.string":"~2.3.3"},"devDependencies":{"expect.js":"~0.2.0","grunt-contrib-jshint":"~0.8.0","grunt-contrib-watch":"~0.5.3","grunt":"~0.4.1","grunt-complexity":"~0.1.3","grunt-cli":"~0.1.9","grunt-sloc":"~0.4.2","sinon":"~1.7.3","time-grunt":"~0.2.5","grunt-bump":"0.0.13","mocha":"~1.16.2","grunt-mocha-cli":"~1.4.0"},"_id":"circuitbox@1.0.0-alpha.1","dist":{"shasum":"43706e7a83c2368e1761a20578d3a4fb4f614f13","tarball":"https://registry.npmjs.org/circuitbox/-/circuitbox-1.0.0-alpha.1.tgz","integrity":"sha512-B+jdHd759YpJuM43YzkuOGtVul4XutNoN3ads9gE/0BsJIqxMdjQ1lY9zYkgv1fYijHvqjfzU0/opoWHR82Pog==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGBmz7QOXRyzmMOR40A6l7jW9THW+GYH3vTr0l3sQW/hAiBAvzcrTzDcBEhxSjdIpjyFP/sGo8xADNV6cbWhXopTwg=="}]},"_from":".","_npmVersion":"1.3.21","_npmUser":{"name":"oddjobsman","email":"oddjobsman@oddjobsman.me"},"maintainers":[{"name":"oddjobsman","email":"oddjobsman@oddjobsman.me"}],"directories":{}},"1.0.0-alpha.2":{"name":"circuitbox","version":"1.0.0-alpha.2","description":"A dependency-injection framework for node.js","main":"./lib/index.js","homepage":"http://circuitbox.oddjobsman.me","scripts":{"test":"node_modules/.bin/gulp ci"},"engines":{"node":">=0.8"},"repository":{"type":"git","url":"https://github.com/oddjobsman/circuitbox"},"keywords":["ioc","di","dependency injection"],"author":{"name":"oddjobsman","email":"oddjobsman@ranganathkini.com"},"license":"MIT","bugs":{"url":"https://github.com/oddjobsman/circuitbox/issues"},"dependencies":{"async":"~0.2.9","underscore":"~1.5.2","when":"~2.7.0","underscore.string":"~2.3.3"},"devDependencies":{"expect.js":"~0.2.0","sinon":"~1.7.3","mocha":"~1.16.2","gulp":"~3.2.2","gulp-load-tasks":"~0.1.0","sloc":"0.0.4","jshint-stylish":"~0.1.4","gulp-sloc":"~1.0.0","gulp-mocha":"~0.2.0","gulp-jshint":"~1.3.4"},"_id":"circuitbox@1.0.0-alpha.2","dist":{"shasum":"4002dcfe684ba99ff9a5b427e7ad9e04292c06fa","tarball":"https://registry.npmjs.org/circuitbox/-/circuitbox-1.0.0-alpha.2.tgz","integrity":"sha512-bYrhQCEYaVsXL2M2UGYBPVSwvPn+uEIW233b7JvQpbqXCQClxepcwAQiPE5gHJ/wZh1eDgq5a+pjA7qIsGGAaA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICtyCjFgSPS1lY/yvkZtHDjQ+9z7XueIIuke7Jb/PKHFAiEA5NyVpwybvdv6EAoJ33CTQwgOL8pZyhOqI9uXBbisjXI="}]},"_from":".","_npmVersion":"1.3.21","_npmUser":{"name":"oddjobsman","email":"oddjobsman@oddjobsman.me"},"maintainers":[{"name":"oddjobsman","email":"oddjobsman@oddjobsman.me"}],"directories":{}},"1.0.0":{"name":"circuitbox","version":"1.0.0","description":"A dependency-injection framework for node.js","main":"./lib/index.js","homepage":"http://circuitbox.oddjobsman.me","scripts":{"test":"node_modules/.bin/gulp ci"},"engines":{"node":">=0.8"},"repository":{"type":"git","url":"https://github.com/oddjobsman/circuitbox"},"keywords":["ioc","di","dependency injection"],"author":{"name":"oddjobsman","email":"oddjobsman@ranganathkini.com"},"license":"MIT","bugs":{"url":"https://github.com/oddjobsman/circuitbox/issues"},"dependencies":{"async":"~0.2.9","underscore":"~1.5.2","when":"~2.7.0","underscore.string":"~2.3.3"},"devDependencies":{"expect.js":"~0.2.0","sinon":"~1.7.3","mocha":"~1.16.2","gulp":"~3.2.2","gulp-load-tasks":"~0.1.0","sloc":"0.0.4","jshint-stylish":"~0.1.4","gulp-sloc":"~1.0.0","gulp-mocha":"~0.2.0","gulp-jshint":"~1.3.4"},"_id":"circuitbox@1.0.0","dist":{"shasum":"8a6a811a289cbbd662ec7ef58f57a60b7cc035fa","tarball":"https://registry.npmjs.org/circuitbox/-/circuitbox-1.0.0.tgz","integrity":"sha512-mVQ33jiBaOs/baeuYVFnGNVAxjZLGhcK603L+hK+hJPBsVpIYsLHrizICdVeIWwPq9n6IDVtEQBCcXJc6Qtm9A==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCWHazQeslFBJqPEHSHzIsbBQwgLRcJu/gkOSMwq2/fNgIhAPoY234lLvmnVJco0aRPs5EH6KNhfxqgY4bcsRanPaXQ"}]},"_from":".","_npmVersion":"1.3.21","_npmUser":{"name":"oddjobsman","email":"oddjobsman@oddjobsman.me"},"maintainers":[{"name":"oddjobsman","email":"oddjobsman@oddjobsman.me"}],"directories":{}},"1.0.1":{"name":"circuitbox","version":"1.0.1","description":"A dependency-injection framework for node.js","main":"./lib/index.js","homepage":"http://circuitbox.oddjobsman.me","scripts":{"test":"node_modules/.bin/gulp ci"},"engines":{"node":">=0.8"},"repository":{"type":"git","url":"https://github.com/oddjobsman/circuitbox"},"keywords":["ioc","di","dependency injection"],"author":{"name":"oddjobsman","email":"oddjobsman@ranganathkini.com"},"license":"MIT","bugs":{"url":"https://github.com/oddjobsman/circuitbox/issues"},"dependencies":{"async":"~0.2.9","underscore":"~1.5.2","when":"~2.7.0","underscore.string":"~2.3.3"},"devDependencies":{"expect.js":"~0.2.0","sinon":"~1.7.3","mocha":"~1.16.2","gulp":"~3.2.2","gulp-load-tasks":"~0.1.0","sloc":"0.0.4","jshint-stylish":"~0.1.4","gulp-sloc":"~1.0.0","gulp-mocha":"~0.2.0","gulp-jshint":"~1.3.4"},"_id":"circuitbox@1.0.1","dist":{"shasum":"e203b670469fc6da9c3156e0e2cf3c8b4e4da5e1","tarball":"https://registry.npmjs.org/circuitbox/-/circuitbox-1.0.1.tgz","integrity":"sha512-luHO41pfomagsxWd+e9RqXjb/q/Z6BEEw0xf4m8ked3ZuNbdoj2zAszERPHHGa2iTgG9q3fnSVuav+Z9uhR7cQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGmY4pB/jMnkSr7+VHOhQ6M+PpO4j3VyF16j7dTSxJXsAiEAgEbEZb6q4IX8EznxS5kN4MKDaunqSXpnse49E6VdW+w="}]},"_from":".","_npmVersion":"1.3.21","_npmUser":{"name":"oddjobsman","email":"oddjobsman@oddjobsman.me"},"maintainers":[{"name":"oddjobsman","email":"oddjobsman@oddjobsman.me"}],"directories":{}},"1.0.2":{"name":"circuitbox","version":"1.0.2","description":"A dependency-injection framework for node.js","main":"./lib/index.js","homepage":"http://circuitbox.oddjobsman.me","scripts":{"test":"node_modules/.bin/gulp ci"},"engines":{"node":">=0.8"},"repository":{"type":"git","url":"https://github.com/oddjobsman/circuitbox"},"keywords":["ioc","di","dependency injection"],"author":{"name":"oddjobsman","email":"oddjobsman@ranganathkini.com"},"license":"MIT","bugs":{"url":"https://github.com/oddjobsman/circuitbox/issues"},"dependencies":{"async":"~0.2.9","when":"~2.7.0","underscore.string":"~2.3.3","lodash":"~2.4.1"},"devDependencies":{"expect.js":"~0.2.0","sinon":"~1.7.3","mocha":"~1.16.2","gulp":"~3.2.2","gulp-load-tasks":"~0.1.0","sloc":"0.0.4","jshint-stylish":"~0.1.4","gulp-mocha":"~0.2.0","gulp-jshint":"~1.3.4","gulp-sloc":"~1.0.1"},"_id":"circuitbox@1.0.2","dist":{"shasum":"74a8131fa8c401af3ae7972a20196fd63ecb8628","tarball":"https://registry.npmjs.org/circuitbox/-/circuitbox-1.0.2.tgz","integrity":"sha512-MCwM4AYhMyS4QKLTm2dJaI9osdUeC74AynsB/poigDubwpKToBm1EtCPquC8r711YvKF64n2/3poLjjnmhbzOw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCV11IKizO60x5gvZiJGmiNZ6gG62UvyzCHJa9+Mue1dAIgTXL/cHnPJrIzdZmtnT5KPf/2beaFrhr70Ok3P+BtXW0="}]},"_from":".","_npmVersion":"1.3.21","_npmUser":{"name":"oddjobsman","email":"oddjobsman@oddjobsman.me"},"maintainers":[{"name":"oddjobsman","email":"oddjobsman@oddjobsman.me"}]},"2.0.0-alpha.1":{"name":"circuitbox","version":"2.0.0-alpha.1","description":"A dependency-injection framework for node.js","main":"./lib/index.js","homepage":"http://circuitbox.oddjobsman.me","scripts":{"test":"gulp ci","coveralls":"istanbul cover _mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | coveralls && rm -rf ./coverage"},"engines":{"node":">=0.9"},"repository":{"type":"git","url":"https://github.com/circuitbox/circuitbox"},"keywords":["ioc","di","dependency injection"],"author":{"name":"Circuitbox Team"},"license":"MIT","bugs":{"url":"https://github.com/circuitbox/circuitbox/issues"},"dependencies":{"underscore":"~1.6.0","async":"~0.2.10","q":"~1.0.0"},"devDependencies":{"mocha-lcov-reporter":"0.0.1","jshint-stylish":"~0.1.5","chai":"~1.9.0","sinon":"~1.8.2","gulp-load-plugins":"~0.3.0","mocha":"~1.17.1","istanbul":"~0.2.4","gulp-mocha":"~0.4.1","coveralls":"~2.8.0","gulp-plumber":"~0.5.6","gulp-sloc":"~1.0.3","gulp":"~3.5.2","gulp-jshint":"~1.5.0"},"_id":"circuitbox@2.0.0-alpha.1","dist":{"shasum":"b0f379698809fa5dfb510d82f1f74d733b993406","tarball":"https://registry.npmjs.org/circuitbox/-/circuitbox-2.0.0-alpha.1.tgz","integrity":"sha512-WxfqTgqE8IQA+BzbYI0N7coNFmD2Z+ey0sGAVy/aFq1m0sCteLxnaaSkDwMuEUx9UTVnQEjGtQXSYKAP1ABq3A==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDGTvlM/h+/tgREl1BBMH518n/BDgGMITYC/NhYDfb1gQIhAL82rrAUpwMHWoIwxE8hGU473huKpbtF8iT5tqhhw0el"}]},"_from":".","_npmVersion":"1.3.24","_npmUser":{"name":"oddjobsman","email":"oddjobsman@oddjobsman.me"},"maintainers":[{"name":"oddjobsman","email":"oddjobsman@ranganathkini.com"}]},"2.0.0-alpha.2":{"name":"circuitbox","version":"2.0.0-alpha.2","description":"A dependency-injection framework for node.js","main":"./lib/index.js","homepage":"http://circuitbox.oddjobsman.me","scripts":{"test":"gulp ci","coveralls":"istanbul cover _mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | coveralls && rm -rf ./coverage"},"engines":{"node":">=0.9"},"repository":{"type":"git","url":"https://github.com/circuitbox/circuitbox"},"keywords":["ioc","di","dependency injection"],"author":{"name":"Circuitbox Team"},"license":"MIT","bugs":{"url":"https://github.com/circuitbox/circuitbox/issues"},"dependencies":{"underscore":"~1.6.0","async":"~0.2.10","q":"~1.0.0"},"devDependencies":{"mocha-lcov-reporter":"0.0.1","jshint-stylish":"~0.1.5","chai":"~1.9.0","sinon":"~1.8.2","gulp-load-plugins":"~0.3.0","mocha":"~1.17.1","istanbul":"~0.2.4","gulp-mocha":"~0.4.1","coveralls":"~2.8.0","gulp-plumber":"~0.5.6","gulp-sloc":"~1.0.3","gulp":"~3.5.2","gulp-jshint":"~1.5.0"},"_id":"circuitbox@2.0.0-alpha.2","dist":{"shasum":"277e2c1e7bf95918b45404a96a07fdaf9a712f8e","tarball":"https://registry.npmjs.org/circuitbox/-/circuitbox-2.0.0-alpha.2.tgz","integrity":"sha512-CAbMO81x/bCwtv/i45flmalpfTuQ/e1H+SFV4eKFsRxaPy+AsCPyrduYZgkSyQvTbmKPsz3DmYFrcaoA91fLwQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDX1VNw44hJQRdSoFVK/L5+wGiHGcMVjHfCUhvkykWBfwIhAJzlVIP/nQbB1XLsjCcXP/n6ckcYhucsMq9T0+jtFngv"}]},"_from":".","_npmVersion":"1.3.24","_npmUser":{"name":"oddjobsman","email":"oddjobsman@oddjobsman.me"},"maintainers":[{"name":"oddjobsman","email":"oddjobsman@ranganathkini.com"}]},"2.0.1":{"name":"circuitbox","version":"2.0.1","description":"A dependency-injection framework for node.js","main":"./lib/index.js","homepage":"http://circuitbox.oddjobsman.me","scripts":{"test":"gulp ci","coveralls":"istanbul cover _mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | coveralls && rm -rf ./coverage"},"engines":{"node":">=0.9"},"repository":{"type":"git","url":"https://github.com/circuitbox/circuitbox"},"keywords":["ioc","di","dependency injection"],"author":{"name":"Circuitbox Team"},"license":"MIT","bugs":{"url":"https://github.com/circuitbox/circuitbox/issues"},"dependencies":{"async":"^0.7.0","q":"^1.0.1","underscore":"^1.6.0"},"devDependencies":{"chai":"^1.9.1","coveralls":"^2.10.0","gulp":"^3.6.1","gulp-jshint":"^1.5.3","gulp-load-plugins":"^0.5.0","gulp-mocha":"^0.4.1","gulp-plumber":"^0.6.1","gulp-sloc":"~1.0.3","istanbul":"^0.2.7","jshint-stylish":"^0.1.5","mocha":"^1.18.2","mocha-lcov-reporter":"0.0.1","sinon":"^1.9.1"},"_id":"circuitbox@2.0.1","_shasum":"27935f5d43c3ba423fe181d5fee75911082e3837","_from":".","_npmVersion":"1.4.7","_npmUser":{"name":"oddjobsman","email":"ranganath.kini@myntra.com"},"maintainers":[{"name":"oddjobsman","email":"oddjobsman@ranganathkini.com"}],"dist":{"shasum":"27935f5d43c3ba423fe181d5fee75911082e3837","tarball":"https://registry.npmjs.org/circuitbox/-/circuitbox-2.0.1.tgz","integrity":"sha512-7g/zXvXsmwLySQyhwiMuQVwAnNhByoyaFoRwDG+MUzYsVBju0aYzU/48IvHSEPwoHI9TXr2vIS+kIWW9G4JFAQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCCEF+SIb+y1p8yw74FNa/BCECjtho62Sytvv8fmJ7CaQIgViRFkFg+AXLJr0TnRTazbgkJxeLQ4ko4N2AvETEoVAg="}]}},"2.5.0":{"name":"circuitbox","version":"2.5.0","description":"A dependency-injection framework for node.js","main":"./lib/index.js","homepage":"http://circuitbox.oddjobsman.me","scripts":{"test":"make","coveralls":"istanbul cover _mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | coveralls && rm -rf ./coverage"},"engines":{"node":">=0.10"},"repository":{"type":"git","url":"https://github.com/circuitbox/circuitbox"},"keywords":["ioc","di","dependency injection"],"author":{"name":"Ranganath Kini","email":"codematix@codematix.me"},"contributors":[{"name":"intuitivcloud Engineering"}],"license":"MIT","bugs":{"url":"https://github.com/circuitbox/circuitbox/issues"},"dependencies":{"async":"^0.9.0","lodash":"^3.7.0","q":"^1.2.0"},"devDependencies":{"chai":"^2.2.0","coveralls":"^2.11.2","istanbul":"^0.3.13","jshint":"^2.7.0","jshint-stylish":"^1.0.1","mocha":"^2.2.4","mocha-lcov-reporter":"0.0.2","sinon":"^1.14.1"},"gitHead":"03288ab6ef03191c7c663c46867751fa9855bbca","_id":"circuitbox@2.5.0","_shasum":"172565728805a62f678912cb0691254373a58f9d","_from":".","_npmVersion":"2.7.6","_nodeVersion":"0.10.38","_npmUser":{"name":"intuitivcloud","email":"engineering@intuitivcloud.com"},"dist":{"shasum":"172565728805a62f678912cb0691254373a58f9d","tarball":"https://registry.npmjs.org/circuitbox/-/circuitbox-2.5.0.tgz","integrity":"sha512-ykppR3BfW/okdesnIUQVnce75dQ7YiaMyS6/Vl2/pBG3DGm2TOStLN+5Tf9Xf7sC5BuFT4g7uMSNMnCt7VkoVQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDyi8pH+r03GkrF+dGuqo6R2wp9a+P4Fwb42jHOd19DsAIhAMsKxtZZM1b136IVV1qO4DBrl3SLR/gqxuewWYqevhV/"}]},"maintainers":[{"name":"intuitivcloud","email":"engineering@intuitivcloud.com"},{"name":"codematix","email":"codematix@intuitivcloud.com"}]},"2.6.0":{"name":"circuitbox","version":"2.6.0","description":"A dependency-injection framework for node.js","main":"./lib/index.js","homepage":"http://circuitbox.oddjobsman.me","scripts":{"test":"make","coveralls":"istanbul cover _mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | coveralls && rm -rf ./coverage"},"engines":{"node":">=0.10"},"repository":{"type":"git","url":"https://github.com/circuitbox/circuitbox"},"keywords":["ioc","di","dependency injection"],"author":{"name":"Ranganath Kini","email":"codematix@codematix.me"},"contributors":[{"name":"intuitivcloud Engineering"}],"license":"MIT","bugs":{"url":"https://github.com/circuitbox/circuitbox/issues"},"dependencies":{"async":"^0.9.0","lodash":"^3.7.0","minimatch":"^2.0.4","q":"^1.2.0"},"devDependencies":{"chai":"^2.2.0","coveralls":"^2.11.2","istanbul":"^0.3.13","jshint":"^2.7.0","jshint-stylish":"^1.0.1","mocha":"^2.2.4","mocha-lcov-reporter":"0.0.2","sinon":"^1.14.1"},"gitHead":"d2747fc4120c83391a717a47836de5a59fdb2249","_id":"circuitbox@2.6.0","_shasum":"f8d38917dcd2a1e6da260f7b7c6cee3ab8b297b1","_from":".","_npmVersion":"1.4.28","_npmUser":{"name":"intuitivcloud","email":"engineering@intuitivcloud.com"},"maintainers":[{"name":"intuitivcloud","email":"engineering@intuitivcloud.com"},{"name":"codematix","email":"codematix@intuitivcloud.com"}],"dist":{"shasum":"f8d38917dcd2a1e6da260f7b7c6cee3ab8b297b1","tarball":"https://registry.npmjs.org/circuitbox/-/circuitbox-2.6.0.tgz","integrity":"sha512-Qk2hJ9wiGOJeFUfAd0DGL30bNVc9RRwmsPC4c5KBhKHBDaYPTvmJoq4xjXIRskd/3V7dG8MUiiCUtCsPWxyJFA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDW34PZndqy90j6UFkFO8GqFD/ePx/2xetylm5XUeZ4zAiA2cAPvgCzIgU1iPJuRNJw/M6nq6gmlsroL1ljwTBMnZQ=="}]}}},"readme":"# circuitbox\n\nA dependency injection framework for node.js. It does true dependency injection and also supports asynchronous creation and initialization of components.\n\n[![NPM version](https://img.shields.io/npm/v/circuitbox.svg)](https://www.npmjs.com/package/circuitbox)\n[![build status](https://img.shields.io/travis/circuitbox/circuitbox.svg)](http://travis-ci.org/circuitbox/circuitbox)\n[![dependency status](https://img.shields.io/david/circuitbox/circuitbox.svg)](https://david-dm.org/circuitbox/circuitbox)\n[![Coverage Status](https://img.shields.io/coveralls/circuitbox/circuitbox.svg)](https://coveralls.io/r/circuitbox/circuitbox?branch=master)\n\n[![NPM](https://nodei.co/npm/circuitbox.png?stars=true&downloads=true)](https://nodei.co/npm/circuitbox/)\n\nIts design has been influenced by frameworks like [Spring](http://projects.spring.io/spring-framework/) and [Google Guice](https://code.google.com/p/google-guice/) and [StructureMap](http://docs.structuremap.net/).\n\n## Installation\n\nThis module can be installed via npm:\n\n``` bash\n$ npm install --save circuitbox\n```\n\n### tl;dr Example\n\nAssuming there is a file named `consoleMessagePrinter.js` in the same folder with the code:\n\n``` js\n'use strict';\n\n// Our console message printer\n// deps is injected by circuitbox with the dependencies\nfunction ConsoleMessagePrinter(deps) {\n  return {\n    print: function () {\n      console.log(deps.messageSource.message());\n    }\n  };\n}\n\nmodule.exports = ConsoleMessagePrinter;\n```\n\nAnd in our `main.js` file we have code as:\n\n``` js\n'use strict';\n\n// our simple message source\n// deps is injected by circuitbox with the dependencies\nvar simpleMessageSource = function (deps) {\n  return {\n    message: function () {\n      return deps.message;\n    }\n  };\n};\n\n// require circuitbox\nvar circuitbox = require('circuitbox');\n\n// create a circuitbox\ncircuitbox.create({\n  modules: [\n    function (registry) {\n      // the message to be used\n      registry.for('message').use('This is the message');\n\n      // define the message source\n      registry.for('messageSource').use(simpleMessageSource)\n        .dependsOn('message');\n\n      // define the message printer - does a module.require internally\n      registry.for('messagePrinter').requires('./consoleMessagePrinter')\n        .dependsOn('messageSource');\n    }\n  ]\n}).then(function (cbx) {\n\n  // get the message printer and print a message\n  cbx.get('messagePrinter').then(function (printer) {\n    printer.print();\n  }, function (err) {\n    console.log('Could not recieve a printer');\n    return;\n  });\n\n}, function (err) {\n  console.log('Could not create circuitbox');\n});\n```\n\n### Motivation\n\n#### Application Size\n\nThe node.js platform was for long dismissed as a platform to build hobby projects and toy project. However that view has now changed. node.js has become a serious application development platform.\n\nThis seriousness has now led many organizations to consider building enterprise-scale applications with node. Now that people are building these large-scale applications, the idea of modularity, componentizing and dependency injection take more prominence.\n\nFrom my experience, no application starts big. All applications start small and then grow large. As applications grow the number of moving parts that need to work together also grows. Unless there is a lot of discipline applied, managing these little parts and ensuring they work together accurately can be quite a challenge.\n\nI see dependency-injection as an important core capability to address this challenge. It has been battle tested in other popular platforms like Java/.NET. DI allows you to cleanly identify components and efficiently manage dependencies between them.\n\n#### Tight Coupling\nOne of the pain points I built circuitbox to solve was the tight-coupling and testability of node.js modules. I believe, though JavaScript has a dynamic type-system, it is not free from the problems of tight-coupling. In node, each uses the `require` method to import code from other modules. Although this is a core feature of node, it actually introduces tight-coupling between the two modules.\n\nI would consider node's `require` to be Java/C#'s (or even JavaScript) `new` operator. Newing up objects internally causes tight coupling between two objects or in node's case two modules.\n\n#### Code smells\nA problem I have experienced while maintaining some PHP code is where one file has several includes. This causes the file to be very fragmented and very difficult to read and maintain. Unfortunately, I have seen a lot of projects where code was being ported over from PHP but not restructured or re-structured poorly. And the problems with fragmented code comes into node.js too.\n\nSome particulars problems I have come to experience are:\n\n- Module code interspersed with `require` calls makes its readablity and maintainability hard.\n- Referencing modules within your library using the package name assuming they are always hosted inside another.\n- Dynamic `require` calls where you are not sure which module gets imported.\n\nI am not claiming that all of these problems can be solved with dependency injection. It would take some discipline from the developers and a little nudge from the frameworks/tools you use to prevent the pitfalls.\n\n#### Testability\nUsing a TDD/BDD workflow really changes the way you approach the construction and maintenance of your code. I do not want to write another rant about how useful these workflows are except to say they should be a quint-essential part of your development process and practice.\n\nTightly coupled modules are hard to test. You really have to work hard for it and use [magic](https://github.com/thlorenz/proxyquire) to stub out the internal uses of `require` in a node.js module. The community is divided over a reliable method to stub `require` calls out. You do not want to spend a lot of time stubbing dependencies when testing a component. If you do, then TDD/BDD is not working for you.\n\n#### Dependency Injection vs. Dependency Lookup\nCurrently, there are a lot of libraries out there that claim to do dependency-injection, [about 40 of them](https://npmjs.org/browse/keyword/dependency%20injection). By my assessment, I saw that a significant number of them don't do dependency-injection. Case-in-point, the [desire](https://npmjs.org/package/desire) framework:\n\n```js\nvar App = function(desire) {\n\n  var ui = desire('ui')\n  var version = desire('version')\n\n  return {\n    run: function() {\n      console.log('application version ' + version)\n      ui.show()\n      console.log('ui is visible')\n    }\n  }\n\n}\n```\nHere `App` is a function that creates an object with a `run` method. See how it is doing dependency lookup in the line `var ui = desire('ui')`? The `desire` container is not smart enough to automatically inject `ui` into `App` and make it available for use. Most frameworks seem to have used this style.\n\nThis is not dependency injection but dependency lookup where the container is simply acting as a registry of components and each component has to lookup this registry and retrieve its dependencies before execution. The problem here is that the names of the components are still hard-wired into the target components and that becomes hard for changing things later. For instance, what if I wanted 2 different types of `ui` components later, one named `webui` and other named `androidui` and `App` would need to use the right one based on where it has started?\n\nFor dependency injection to work, the container must first be given (or detect) the component configuration ahead-of-time. During execution, when the program asks the container for a component, the container uses the target component's configuration, assembles its dependencies, creates & initializes the target component and then gives it to the program for use.\n\n#### Lock-In\nIn the `desire` code example shown above, also observe the lock-in. Since you are directly accessing the `desire` container, you are bound to `desire`'s API and if you decide to move away from the library, you will need to change your code at several places where there is a reference to `desire`.\n\nYou do not want this kind of forced relationship with a framework.\n\n### Design Principles\n1. Provide true dependency injection where container knows all the components it hosts and knows how to create, initialize them with their dependencies.\n2. Support node.js' asynchronus style. The asynchronous style is one of the key differentiators for apps built on node. It is very core to node being fast and scalable. I wanted to ensure I bring this style to circuitbox ensuring that components might need to be created or initialized asynchronously.\n3. Encourage components to be testable\n4. Be nice, dont lock-in - provide a simple way to wire components together without requiring components to be tightly-coupled with `circuitbox`.\n5. Allow existing node.js library modules to be used with circuitbox and provide the same DI facility for them.\n\n### A Taste of Circuitbox\n\nSo lets take a look at `circuitbox`, first let me define a component in a file `consoleMessagePrinter.js` with the code:\n\n```js\nmodule.exports = function ConsoleMessagePrinter(deps) {\n  'use strict';\n\n  return {\n    print: function () {\n      console.log(deps.messageSource.message());\n    }\n  };\n}\n```\n\nNotice here that the code looks quite close dependency lookup style code of the `desire` example I provided earlier. However, the component does not get direct access to the registry. It gets a parameter called `deps` which at runtime will include all the dependencies that was declared for the component. The component then takes a reference of its dependency and uses it. In this case `ConsoleMessagePrinter` uses a `messageSource` as a dependency to get the message which it prints to the `console`.\n\nThe point to notice here is that you wrap your component code with a function closure that takes the component's dependencies as a parameter. It then returns the actual component which will be used by other components. I call this function closure as a 'creator function' or 'creator'.\n\nWrapping your existing component code with a 'creator' is probably the only thing that `circuitbox` asks you do to make the component dependency injectable.\n\nNext, lets define the `messageSource` component and how we can wire this up with `circuitbox`. I put the following code in a file called `main.js`:\n\n```js\n'use strict';\n\nvar simpleMessageSource = function (deps) {\n  return {\n    message: function () {\n      return deps.message;\n    }\n  };\n};\n\n// require circuitbox\nvar circuitbox = require('circuitbox');\n\n// create a circuitbox\ncircuitbox.create({\n  modules: [\n    function (registry) {\n      // the message to be used\n      registry.for('message').use('This is the message');\n\n      // define the message source\n      registry.for('messageSource').use(simpleMessageSource)\n        .dependsOn('message');\n\n      // define the message printer - does a module.require internally\n      registry.for('messagePrinter').requires('./consoleMessagePrinter')\n        .dependsOn('messageSource');\n    }\n  ]\n}).then(function (cbx) {\n\n  // get the message printer and print a message\n  cbx.get('messagePrinter').then(function (printer) {\n    printer.print();\n  }, function (err) {\n    console.log('Could not recieve a printer');\n    return;\n  });\n\n}, function (err) {\n  console.log('Could not create circuitbox');\n});\n```\n\nIn this snippet, we initially define a `simpleMessageSource` component which also is wrapped in a creator. It needs a `message` as a dependency which is provided via the `deps` parameter.\n\nWe then import the `circuitbox` library and create a new instance of it using the `create` method. The method takes component configuration as an object hash in its parameter. This configuration object should contain a `modules` attribute that represents an `Array` of functions that define modules. Modules are a good way of logically grouping your components. `circuitbox` provides a fluent API to express component definitions to help readability.\n\nIn this case we have a single module function which accepts one parameter named `registry`. It represents the component registry that `circuitbox` will use to lookup components. This function is where modules can define the components to `circuitbox` that must be served during runtime.\n\nFirst, we define the `message` component which is a simple string value. Yes, components can be complex functions, objects, arrays, strings, booleans, numbers. Even `null` value. The definition starts with the `for` method where we provide the name of the component and chain to the `use` method to tell `circuitbox` to use the specified value as the component.\n\nThe next component we define is the `messageSource`. Note that the component is defined in the same file. Again, we call the`for` and `use` method to point it to the `simpleMessageSource` creator function. We then chain on to call the `dependsOn` where we declare that `messageSource` depends on `message`. This is the way we tell `circuitbox` about a component's depdendencies and it will do the injection at runtime. The injection logic `circuitbox` uses is name-based. So ensure you name your components correctly.\n\nFinally we define the `messagePrinter` component. Here we start the definition with a `for` but then call the `requires` method and pass it the path of the `consoleMessagePrinter.js` module. This method tell `circuitbox` to use node.js's `require` method to import an external module. This imports the code from the file and points to the `ConsoleMessagePrinter` component we discussed earlier.\n\nGreat, so far so good. Now we have defined all our components to `circuitbox`, so how do we kickstart? In the spirit of asynchronous style of node.js, `circuitbox` implements asynchronous constructs in many places:\n\n1. Creating an `circuitbox` is asynchronous\n2. A component creator function can be asynchronous\n3. A component initializer function can also be asynchronous\n2. Component retrieval is asynchronous.\n\n`circuitbox` provides 2 styles of asynchronous constructs, the [callback](http://book.mixu.net/node/ch7.html) style and the promises style. The `create` method on `circuitbox` not only takes the component configuration, you can optionally specify a callback function as the second parameter. This callback function takes 2 parameter an `err` parameter and the `circuitbox` parameter. The former is provided if there was an error initializing the configuration and creating a container. The latter is a fully initialized `circuitbox` DI container which can be used to request components.\n\nThe above code snippet demonstrates the [promise](http://promises-aplus.github.io/promises-spec/) style of asynchronous constructs. `circuitbox` uses the [Q](https://github.com/kriskowal/q) library for implementing promises. If the `create` method is not provided a callback, it triggers an initialization of the DI container and returns a promise object. We chain onto the promise object and call the `done` method which receives a fully initialized `circuitbox` container.\n\nRegardless of the style you prefer to use, once you have a instance of `circuitbox` container, you can call the `get` method passing the name of the component you require. Like the `create` method, the `get` method also takes an optional callback which is called when the requested component is created and initialized. As demonstrated above, the `get` method also returns a promise object in the absence of a callback argument.\n\n### Components\n\nComponents are objects which provide a service. They usually collaborate with other components that provide other required services. circuitbox prescribes a specific convention with which you can author your components. This conventions helps the component recieve the required dependencies. Below is an example of a component:\n\n\n``` js\nmodule.exports = function CreditCardProcessor (processor, transactionLog) {\n\tthis.chargeOrder = function (order, creditCard) {\n\t\tvar tx = processor.processTransaction(creditCard, order.amount);\n\t\ttransactionLog.recordPayment(tx);\n\t};\n};\n```\n\n### Roadmap\nSo what are the next set of features on the project?\n\n- Support for aliasing components with additional names\n- Support for the browser - via [browserify](http://browserify.org/)\n- Bindings to popular libraries. These however, will be published as separate libraries. I am considering  libraries such as:\n  -  express - In progress. See [circuitbox-express](https://github.com/circuitbox/circuitbox-express)\n  -  redis - In progress. See [circuitbox-redis](https://github.com/circuitbox/circuitbox-redis)\n  -  mongoose\n  -  mysql\n\n\nHead over to the [waffle.io](https://waffle.io/circuitbox/circuitbox) page - [![Stories in Ready](https://badge.waffle.io/circuitbox/circuitbox.png?label=ready)](https://waffle.io/circuitbox/circuitbox) for a better view of things to come.\n\n## Contributing\n\n1. Fork it\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Follow the [coding conventions](http://github.com/circuitbox/circuitbox/wiki/Coding-Conventions)\n4. Commit your changes (`git commit -am 'Add some feature'`)\n5. Push to the branch (`git push origin my-new-feature`)\n6. Create new Pull Request","maintainers":[{"email":"engineering@intuitivcloud.com","name":"ranganath.kini"},{"email":"codematix@codematix.me","name":"codematix"}],"time":{"modified":"2022-06-13T06:03:06.175Z","created":"2013-12-30T12:53:42.475Z","1.0.0-alpha.1":"2013-12-30T12:53:42.475Z","1.0.0-alpha.2":"2014-01-04T12:43:00.770Z","1.0.0":"2014-01-06T13:05:43.893Z","1.0.1":"2014-01-08T02:20:39.054Z","1.0.2":"2014-01-08T18:26:04.980Z","2.0.0-alpha.1":"2014-02-26T06:33:17.401Z","2.0.0-alpha.2":"2014-02-26T14:36:59.811Z","2.0.1":"2014-04-17T12:57:19.413Z","2.5.0":"2015-04-17T18:12:16.374Z","2.6.0":"2015-04-27T17:03:33.121Z"},"homepage":"http://circuitbox.oddjobsman.me","keywords":["ioc","di","dependency injection"],"repository":{"type":"git","url":"https://github.com/circuitbox/circuitbox"},"author":{"name":"Ranganath Kini","email":"codematix@codematix.me"},"bugs":{"url":"https://github.com/circuitbox/circuitbox/issues"},"license":"MIT","readmeFilename":"README.md","users":{"oddjobsman":true,"intuitivcloud":true},"contributors":[{"name":"intuitivcloud Engineering"}]}