NodeJS Express 依赖注入和数据库连接
NodeJS Express Dependency Injection and Database Connections
来自非 Node 背景,我的第一直觉是这样定义我的服务
MyService.js
module.exports = new function(dbConnection)
{
// service uses the db
}
现在,我希望每个请求打开一个数据库连接,所以我在中间件中定义:
res.locals.db = openDbConnection();
并且在一些消费快递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
之类的方式......但是现在 [=16= 我将如何将数据库绑定到当前 res.locals
对象] 本身就是一个模块?在 Node 中处理这种瘦身的推荐方法是什么?
更新答案:2015 年 2 月 5 日
如果您想将数据库连接附加到每个请求对象,然后在您的服务中使用该连接,则必须以某种方式将连接传递给 myService
。下面的例子展示了一种方法。如果我们尝试使用 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 年 5 月 1 日
您所说的可以使用快速中间件来完成。它可能是这样的:
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
这样的东西。这并不意味着它不能完成,但你可以考虑这样的方法
// 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!
}
来自非 Node 背景,我的第一直觉是这样定义我的服务
MyService.js
module.exports = new function(dbConnection)
{
// service uses the db
}
现在,我希望每个请求打开一个数据库连接,所以我在中间件中定义:
res.locals.db = openDbConnection();
并且在一些消费快递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
之类的方式......但是现在 [=16= 我将如何将数据库绑定到当前 res.locals
对象] 本身就是一个模块?在 Node 中处理这种瘦身的推荐方法是什么?
更新答案:2015 年 2 月 5 日
如果您想将数据库连接附加到每个请求对象,然后在您的服务中使用该连接,则必须以某种方式将连接传递给 myService
。下面的例子展示了一种方法。如果我们尝试使用 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 年 5 月 1 日
您所说的可以使用快速中间件来完成。它可能是这样的:
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
这样的东西。这并不意味着它不能完成,但你可以考虑这样的方法
// 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!
}