NodeJS Express 依赖注入和数据库连接

3

作为一个非Node背景的人,我的第一反应是这样定义我的服务

MyService.js

module.exports = new function(dbConnection)
{
    // service uses the 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);
});

现在,由于Node的首选依赖注入方法是通过require(...)语句进行的,因此似乎我不应该使用MyService的构造函数来注入db

那么假设我想要拥有

var db = require('db');

MyService的顶部,然后以某种方式使用db.current....但是现在db本身是一个模块,我该如何将db与当前的res.locals对象绑定起来?在Node中处理这种情况有什么推荐的方法吗?

1个回答

1

更新的答案:05/02/15

如果您想将数据库连接附加到每个请求对象中,然后在服务中使用该连接,那么必须以某种方式将该连接传递给myService。以下示例显示了一种方法。 如果我们尝试使用db.current 或类似的内容,我们将在DB模块中存储状态。 根据我的经验,这将导致麻烦。

或者,我可以提供我使用(并仍在使用)的方法,具体请参见this previous answer。对于此示例,这意味着:

// 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模块中解耦出来,只有实际使用它的模块才知道它的存在。

之前的回答:05/01/15

你所说的可以通过使用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 作为参数。既然我们正在讨论如何“处理”节点中的依赖关系/要求,我希望使用 require('db')....而且由于你从未见过 new MyService....那么你会有什么期望呢? - Jeff
嘿,杰夫,我想我更好地理解了你的问题。我已经相应地更新了我的答案。如果我更接近了,请告诉我! - Brennan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接