[英]Node.js, Express and Dependency Injection
我正处于node.js项目的早期阶段,我正在寻求改进整个应用程序组织。 在过去,我使用Symfony2(PHP),现在我在Angular中编写了很多代码,这两者都非常依赖于DI。 所以,我真的很喜欢在node.js项目中应用相同原理的想法。
我知道像Rewire
这样的软件包的存在,但是现在我想尝试DI方法。 问题是, 如何实现均衡以保持轻量级的感觉,使得与节点一起使用经过良好测试的依赖注入应用程序的可靠性 (我知道经过充分测试的是给出了可靠性;-))。
其中一个问题是,如何管理外部模块,如果某个对象需要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()
来调用处理程序,因此上下文丢失,我们无法使用this
。 所以我们留下了这些:
// 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框架? (比如di.js )以及如何保持体验精益 ? 欢迎所有想法。 谢谢!
你有一些好的想法,我想补充一下:
为了在使用节点时保持这种轻量级的感觉,您需要一种不会增加过多复杂性的依赖注入方法。 你上面的明确例子让我想起了Vojta Jina的一次演讲 ,其中他对依赖注入的布线部分提出了重要观点。 (观看分钟3:35到8:05)我无法解释它比Vojtja在他的演讲中做得更好但基本上他说我们需要一个di框架来处理布线(注入什么内容)。 否则,我们手动写入以设置接线的代码将无法维护。 每个单元测试也需要这样的接线代码。 IMO是手动依赖注入不再是一种选择的地方。
当你使用di框架(或许多人说的di容器)时,基本的想法是每个单独的模块都说明它需要哪些依赖项,以及其他模块可以通过哪个id。 然后可以调用di框架来初始化充当入口点的模块(例如app.js),框架将查找所有依赖项并接管注入适当模块实例的艰苦工作。
node.js有很多di框架 ,我想添加自己的框架 : “Fire Up!” 如果您使用它,您的示例将如下所示:
// Fire me up!
function Foo(fs) {
this.fs = fs;
}
Foo.prototype.index = function () {
var self = this;
return function (req, res, next) {
// self.fs...
};
};
module.exports = {
implements: 'foo',
inject: ['require(fs)'],
_constructor: Foo
};
// 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.
运行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的示例。
希望有所帮助!
您可以访问https://www.npmjs.com/package/plus.container
这与Symfony的DIC很接近
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.