Reputation: 2802
I'm building a base library for a distributed application. Here's the structure:
core_project/
lib/
index.js
module1.js
module2.js
...
package.json
Many other parts of my application will use this library like this:
consumer_project/
node_modules/
core_project/
...
app.js
package.json
I want some common dependencies, like the DB handler to be provided by the consumer application. Once initialized, I want all my core application modules to be able to use those dependencies.
I attempted making an module initialization function in every core app module: core_project/lib/module1.js
var cfg = {db: null};
module.exports = {
// ...
'initModule': function (db) {
cfg.db = db;
}
}
And this is my core module index file: core_project/lib/index.js
var modules = {
'module1': require('./module1'),
'module1': require('./module2'),
// ...
};
function create(db) {
var app = {};
init(app, modules, db);
return app;
}
function init(app, mods, db) {
var m;
for (m in mods) {
if (mods.hasOwnProperty(m)) {
if (mods[m].hasOwnProperty('initModule')) {
mods[m].initModule(db);
}
app[m] = mods[m];
}
}
}
module.exports = create;
Now, my consumer app can pass dependencies like this: consumer_project/app.js
var core = require('core_project');
var db = // initialize db
var app = core(db);
// Start using
app.module1.run();
cfg = {db: null}
and export the initModule
function in every module that requires dependencies. Is there a better way to provide consumer provided dependencies like db, logger to a core library and all its modules?
Upvotes: 2
Views: 115
Reputation: 422
Passing in dependencies as arguments (i.e. dependency injection) is a perfectly valid way to achieve this, though you can simplify your init using a closure:
core_project/lib/module1.js:
module.exports = function(db) {
return function() {
// closure scoped with dependencies
// can use db object
};
}
Then your init function would create the closure:
app[m] = mods[m](db);
Passing deps like this is usually desirable for database clients so the same connection is used throughout your modules, however other types of deps like loggers might be better to import using the standard require()
method of the module system e.g. require('winston')
Upvotes: 1