如何提供诸如数据库,logging器等依赖关系到底层库?
build立
我正在为分布式应用程序构build基础库。 结构如下:
core_project/ lib/ index.js module1.js module2.js ... package.json
我的应用程序的许多其他部分将使用这样的库:
consumer_project/ node_modules/ core_project/ ... app.js package.json
问题
我想要一些常见的依赖关系,比如消费者应用程序提供的DB处理程序。 一旦初始化,我希望所有的核心应用程序模块能够使用这些依赖关系。
尝试解决scheme
我试图在每个核心应用程序模块中创build一个模块初始化函数: core_project / lib / module1.js
var cfg = {db: null}; module.exports = { // ... 'initModule': function (db) { cfg.db = db; } }
这是我的核心模块索引文件: 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;
现在,我的消费者应用程序可以像这样传递依赖关系: consumer_project / app.js
var core = require('core_project'); var db = // initialize db var app = core(db); // Start using app.module1.run();
尝试解决scheme的问题
- 我必须添加
cfg = {db: null}
并将initModule
函数导出到每个需要依赖关系的模块中。 - 我必须将每个模块附加到core_project / lib / index.js中的核心应用程序对象
题
有没有更好的方式提供消费者提供的依赖关系,如数据库,logging到核心库及其所有模块?
传递依赖作为参数(即dependency injection)是一个完美的有效的方法来实现这一点,虽然你可以简化你的init使用闭包:
core_project / lib / module1.js :
module.exports = function(db) { return function() { // closure scoped with dependencies // can use db object }; }
然后你的init函数会创build闭包:
app[m] = mods[m](db);
像这样传递代价通常是数据库客户端所希望的,因此在整个模块中使用相同的连接,但是其他types的代码logging器可能会更好地使用模块系统的标准require()
方法导入,例如require('winston')