Javascript Node.js、Express和依赖项注入
我正处于node.js项目的早期阶段,我希望改进整个应用程序组织。过去我使用Symfony2(PHP),现在我用Angular编写了很多代码,这两种语言都非常依赖DI。因此,我非常喜欢在node.js项目中应用相同的原则 我知道这样的包的存在,但现在我想尝试DI方法。问题是,如何实现平衡,以保持轻量级的感觉,即使用经过良好测试的依赖注入应用程序的稳定性来使用node(我知道经过良好测试的应用程序才具有稳定性;-) 节点模块 其中一个问题是如何管理外部模块,如果某个对象需要Javascript Node.js、Express和依赖项注入,javascript,node.js,express,dependency-injection,Javascript,Node.js,Express,Dependency Injection,我正处于node.js项目的早期阶段,我希望改进整个应用程序组织。过去我使用Symfony2(PHP),现在我用Angular编写了很多代码,这两种语言都非常依赖DI。因此,我非常喜欢在node.js项目中应用相同的原则 我知道这样的包的存在,但现在我想尝试DI方法。问题是,如何实现平衡,以保持轻量级的感觉,即使用经过良好测试的依赖注入应用程序的稳定性来使用node(我知道经过良好测试的应用程序才具有稳定性;-) 节点模块 其中一个问题是如何管理外部模块,如果某个对象需要fs模块,该怎么办?正如
fs
模块,该怎么办?正如Vojta Jina(来自AngularJS)所述:
所以现在对我来说最好的方法是这样的:模块是无状态的。它们只包含类/函数/常量的定义
所以,我想我必须注入所有东西:
function Foo(fs) {
this.fs = fs;
}
Foo.prototype.doSomething: function () {
// this.fs...
};
module.exports = Foo;
某处:
var fs = require('fs');
var Foo = require('./Foo');
var foo = new Foo(fs);
foo.doSomething();
快车
由于Express使用apply()
调用处理程序,因此上下文丢失,我们无法使用此
。所以我们只剩下这些:
// foo.js
function Foo(fs) {
this.fs = fs;
}
Foo.prototype.index = function () {
var self = this;
return function (req, res, next) {
// self.fs...
};
};
module.exports = Foo;
// bar.js
module.exports.index = function (fs) {
return function (req, res, next) {
// fs...
};
};
// app.js
var express = require('express');
var fs = require('fs');
var app = express();
var Foo = require('./foo');
var foo = new Foo(fs);
var bar = require('./bar');
app.get('/foo', foo.index());
app.get('/bar', bar.index(fs));
所以
有人采取了这种方法吗?DI框架的使用情况如何?(喜欢)和如何保持体验的精益?欢迎提出任何意见。谢谢 你有一些好的想法,我想补充一下:
- 拥有无状态模块将有助于横向扩展应用程序。如果所有状态都在一个数据库中,那么并行运行多个node.js实例就很容易了
- 我也喜欢注入一切。否则,当我想要编写一个单元测试的时候,它会变得很难,因为我有一个硬编码的(不是注入的)依赖项,我不能模仿它
node index.js
时,您会得到以下输出:
fireUp# INFO Requested: app, implemented in: lib/app.js
fireUp# INFO |-- Requested: require(express)
fireUp# INFO |-- Requested: foo, implemented in: lib/foo.js
fireUp# INFO |-- Requested: require(fs)
fireUp# INFO |-- Requested: bar, implemented in: lib/bar.js
fireUp# INFO |-- Requested: require(fs)
如果这看起来值得一试,您可能会对显示基于express的示例的感兴趣
希望有帮助 您可以查看
这与Symfony中的DIC很接近,有一个疑问,向控制器注入类似“异步”的东西是否有意义?或者仅仅要求它到位不是更方便吗?对于像“path”这样的模块也是一样的。在适当的地方尝试Require会挫败DI的目的,因为每次你想用另一个实现替换依赖项时,你都必须更新Require!如果你不介意的话,你可以更新你的答案来添加一个ES6版本的类吗
// Fire me up!
module.exports = {
implements: 'bar',
inject: ['require(fs)'],
factory: function (fs) {
return {
index: function (req, res, next) {
// fs...
}
};
}
};
// Fire me up!
module.exports = {
implements: 'app',
inject: ['require(express)', 'foo', 'bar']
};
module.exports.factory = function (express, foo, bar) {
var app = express();
app.get('/foo', foo.index());
app.get('/bar', bar.index);
};
var fireUpLib = require('fire-up');
var fireUp = fireUpLib.newInjector({
basePath: __dirname,
modules: ['./lib/**/*.js'] // foo.js, bar.js, app.js are on this path
});
fireUp('app'); // This is where the injection is kicked off.
fireUp# INFO Requested: app, implemented in: lib/app.js
fireUp# INFO |-- Requested: require(express)
fireUp# INFO |-- Requested: foo, implemented in: lib/foo.js
fireUp# INFO |-- Requested: require(fs)
fireUp# INFO |-- Requested: bar, implemented in: lib/bar.js
fireUp# INFO |-- Requested: require(fs)