NodeJS Express依赖注入和数据库连接 [英] NodeJS Express Dependency Injection and Database Connections

查看:255
本文介绍了NodeJS Express依赖注入和数据库连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自非Node背景,我的第一个直觉是这样定义我的服务

Coming from a non Node background, my first instinct is to define my service as such

MyService.js

module.exports = new function(dbConnection)
{
    // service uses the db
}

现在,我希望每个请求一个打开的数据库连接,所以我在中间件中定义:

Now, I want one open db connection per request, so I define in middleware:

res.locals.db = openDbConnection();

并使用一些易用的Express api代码:

And in some consuming Express api code:

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.

Now, being that Node's preferred method of dependency injection is via the require(...) statement, it seems that I shouldn't be using the constructor of MyService for injection of the db.

所以我想拥有

var db = require('db');

MyService顶部的

,然后使用类似db.current的方式....但是既然db本身是模块本身,如何将db绑定到当前的res.locals对象?在Node中处理这种精简的推荐方法是什么?

at the top of MyService and then use somehow like db.current....but how would I tie the db to the current res.locals object now that db is a module itself? What's a recommended way of handling this kind of thin in Node?

推荐答案

更新后的答案:2015年5月2日

如果要将数据库连接附加到每个请求对象,然后在服务中使用该连接,则必须以某种方式将连接传递给myService.下面的示例显示了一种执行此操作的方法.如果尝试使用db.current或类似的方法,我们将状态存储在数据库模块中.以我的经验,那会带来麻烦.

If you want to attach a DB connection to each request object, then use that connection in your service, the connection will have to be passed to myService some how. The example below shows one way of doing that. If we try to use db.current or something to that effect, we'll be storing state in our DB module. In my experience, that will lead to trouble.

或者,我在

Alternatively, I lay out the approach I've used (and still use) in this previous answer. What this means for this example is the following:

// 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.
      }
}

通过这种方法,我们已经将数据库模块与api/app/router模块分离了,只有实际使用它的模块才知道它的存在.

With this approach, we've decoupled the DB module from the api/app/router modules and only the module that actually uses it will know it exists.

上一个答案:15年5月1日

您正在谈论的内容可以使用快速中间件来完成.可能是这样的:

What you're talking about could be done using an express middleware. Here's what it might look like:

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);
});

我个人以前从未在快速申请中见过过像new MyService这样的东西.这并不意味着它无法完成,但是您可以考虑采用这种方法

I personally have never seen something like new MyService before in express applications. That doesn't mean it can't be done, but you might consider an approach like this

// 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!
}

这篇关于NodeJS Express依赖注入和数据库连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆