gpt4 book ai didi

javascript - Node.js、Express 和依赖注入(inject)

转载 作者:数据小太阳 更新时间:2023-10-29 04:42:26 41 4
gpt4 key购买 nike

我正处于 node.js 项目的早期阶段,我希望改进整个应用程序组织。过去我使用 Symfony2 (PHP),现在我用 Angular 编写很多代码,这两者都严重依赖 DI。所以,我真的很喜欢在我的 node.js 项目中应用相同原则的想法。

我知道像 Rewire 这样的包的存在,但现在我想尝试 DI 方法。问题是,如何实现一种平衡,以保持轻量级的感觉,这种感觉使与 Node 一起工作时具有经过良好测试的依赖注入(inject)应用程序的坚固性(我知道经过良好测试才能提供坚固性;-) ).

Node 模块

其中一个问题,将是如何管理外部模块,如果某些对象需要 fs 模块怎么办?正如 Vojta Jina(来自 AngularJS)在 this article 中所述:

So the best way that works for me right now is something like this: Modules are stateless. They only contain definitions of classes/functions/constants.

所以,我想我必须注入(inject)一切:

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

由于 Express 使用 apply() 调用处理程序,因此 context 丢失了,我们不能使用 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)以及如何保持精简体验?欢迎所有想法。谢谢!

最佳答案

你有一些好的想法我想补充一下:

  • 拥有无状态模块将帮助您横向扩展您的应用。如果所有状态都在数据库中,那么并行运行多个 node.js 实例将很容易。
  • 我也更喜欢注入(inject)一切。否则,当我想编写单元测试时,它会变得困难,因为我有一个我无法模拟的硬编码(未注入(inject))依赖项。

为了在使用 Node 时保持这种轻量级的感觉,您需要一种不会增加太多复杂性的依赖注入(inject)方法。你上面的例子让我想起了 talk by Vojta Jina他在其中对依赖注入(inject)的连接部分提出了一个重要观点。 (观看 3:35 到 8:05 分钟)我无法比 Vojtja 在他的演讲中更好地解释它,但基本上他说我们需要一个 di 框架来处理连接(什么被注入(inject)什么)。否则,我们手动编写的用于设置接线的代码将无法维护。此外,每个单元测试都需要这样的接线代码。在 IMO 中,手动依赖项注入(inject)不再是一种选择。

当您使用 di 框架(或许多人所说的 di 容器)时,基本思想是每个单独的模块声明它需要哪些依赖项以及其他模块可以通过哪个 id 请求它。然后可以调用 di 框架来初始化用作入口点的模块(例如 app.js),框架将查找所有依赖项并接管注入(inject)适当模块实例的艰苦工作。

有很多di frameworks for node.js我想添加我自己的:"Fire Up!"如果您使用它,您的示例将如下所示:

foo.js

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

bar.js

// Fire me up!

module.exports = {
implements: 'bar',
inject: ['require(fs)'],
factory: function (fs) {
return {
index: function (req, res, next) {
// fs...
}
};
}
};

应用程序.js

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

索引.js

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)

如果这看起来值得一试,您可能会对 Getting Started section 感兴趣它显示了一个基于 express 的示例。

希望对您有所帮助!

关于javascript - Node.js、Express 和依赖注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24529209/

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com