Node.js NodeJS Express依赖项注入和数据库连接

Node.js NodeJS Express依赖项注入和数据库连接,node.js,mongodb,express,dependency-injection,Node.js,Mongodb,Express,Dependency Injection,我来自一个非节点的背景,我的第一反应就是这样定义我的服务 MyService.js module.exports = new function(dbConnection) { // service uses the db } 现在,我希望每个请求有一个open db连接,因此我在中间件中定义: res.locals.db = openDbConnection(); 在一些使用Express api的代码中: api.js var MyService = require(./ser

我来自一个非节点的背景,我的第一反应就是这样定义我的服务

MyService.js

module.exports = new function(dbConnection)
{
    // service uses the db
}
现在,我希望每个请求有一个open db连接,因此我在中间件中定义:

res.locals.db = openDbConnection();
在一些使用Express api的代码中:

api.js

var MyService = require(./services/MyService')

...

router.get('/foo/:id?', function (req, res) {
    var service = new MyService(res.locals.db);
});
现在,作为该节点首选的依赖注入方法,通过
require(…)
语句,似乎我不应该使用
MyService
的构造函数来注入
db

那么让我们假设我想要

var db = require('db');

MyService
的顶部,然后使用类似于
db.current
…但是既然
db
本身就是一个模块,我如何将db绑定到当前
res.locals
对象?处理这种瘦节点的推荐方法是什么?

更新答案:2015年2月5日

如果要将DB连接连接到每个请求对象,然后在服务中使用该连接,则必须将该连接传递到
myService
some how。下面的示例显示了一种方法。如果我们尝试使用
db.current
或类似的东西,我们将在db模块中存储状态。以我的经验,那将导致麻烦

或者,我列出了我在中使用过(现在仍然使用)的方法。此示例的含义如下所示:

// api.js
var MyService = require(./services/MyService')

...

router.get('/foo/:id?', function (req, res) {
    MyService.performTask(req.params.id);
});


// MyService.js
var db = require('db');
module.exports = {
   performTask: function(id)
      {
         var connection = db.getOpenConnection();
         // Do whatever you want with the connection.
      }
}
通过这种方法,我们将DB模块与api/app/router模块解耦,只有实际使用它的模块才会知道它的存在

先前的答案:2015年1月5日

您所说的可以使用express中间件来完成。下面是它可能的样子:

var db = require('db');

// Attach a DB connection to each request coming in
router.use(req, res, next){
   req.locals.db = db.getOpenConnection();
   next();
}

// Later on..
router.get('/foo/:id?', function (req, res) {
  // We should now have something attached to res.locals.db!
  var service = new MyService(res.locals.db);
});
我个人从未在express应用程序中见过类似于
new MyService
的东西。这并不意味着它不可能完成,但你可以考虑这样的方法

// router.js
var MyService = require('MyService');
router.get('/foo/:id?', function (req, res) {
  MyService.foo(res.locals.db);
});

// MyService.js
module.exports.foo(connection){
  // I have a connection!
}

是的,但现在我的构造函数或MyService中的方法需要db作为参数。既然我们谈论的是如何“接近”节点中的依赖项/需求,我希望需要('db')……既然您从未见过新的MyService……您会期望什么呢?嘿,杰夫,我想我更理解您的问题。我已经相应地更新了我的答案。如果我再靠近一点,请告诉我!