在 Node.js 中使用全局变量进行依赖注入

Che*_*enR 5 dependency-injection global-variables node.js

我正在开始一个基于 Node.js 的长期项目,因此我希望建立一个可靠的依赖注入(DI) 系统。

尽管 Node.js 的核心意味着使用简单的模块 require() 来连接组件,但我发现这种方法并不适合大型项目(例如,要求每个文件中的模块不是可维护、可测试或动态的)。

现在,我做我的研究位张贴了这个问题之前,我已经发现了对Node.js的一些有趣的DI库(见wire.jsdependable.js)。

然而,为了最大程度的简单和最少的重复,我提出了我自己的实施 DI 的主张:

  • 您有一个模块 di.js,它充当容器并通过指向一个 JSON 文件进行初始化,该文件存储了依赖项名称及其各自的 .js 文件的映射。这已经为 DI 提供了动态特性,因为您可以轻松交换测试/开发依赖项。容器可以通过使用 inject() 函数返回依赖项,该函数找到依赖项映射并使用它调用 require() 。

  • 为简单起见,模块被分配给一个全局变量,即 global.$di,以便项目中的任何文件都可以通过调用 $di.inject() 来使用容器/注入器。

这是实现的要点:

文件di.js

module.exports = function(path) {

    this.deps = require(path);

    return {
        inject: function(name) {

                if (!deps[name])
                    throw new Error('dependency "' + name + '" isn\'t registered');
                return require(deps[name]);
        }
    };
};
Run Code Online (Sandbox Code Playgroud)

依赖映射 JSON 文件

{
    "vehicle": "lib/jetpack",
    "fuel": "lib/benzine",
    "octane": "lib/octane98"
}
Run Code Online (Sandbox Code Playgroud)

根据开发/测试模式在主 JavaScript 文件中初始化 $di:

var path = 'dep-map-' + process.env.NODE_ENV + '.json;
$di = require('di')(path);
Run Code Online (Sandbox Code Playgroud)

在某个文件中使用它:

var vehicle = $di.inject('vehicle');
vehicle.go();
Run Code Online (Sandbox Code Playgroud)

到目前为止,我能想到的使用这种方法的唯一问题是全局变量 $di。据说,全局变量是一种不好的做法,但在我看来,我为单个全局变量的成本节省了大量重复。

有什么可以反对我的建议的建议?

mih*_*hai 1

总的来说,这种方法对我来说听起来不错。

全局变量在 Node.js 中的工作方式是,当您声明一个不带var关键字的变量时,它会被添加到在所有模块之间共享的全局对象中。您还可以显式地使用global.varname. 例子:

vehicle = "jetpack"
fuel = "benzine"
console.log(vehicle) // "jetpack"
console.log(global.fuel) // "benzine"
Run Code Online (Sandbox Code Playgroud)

用 声明的变量var仅是模块的本地变量。

var vehicle = "car"
console.log(vehicle) // "car"
console.log(global.vehicle) // "jetpack"
Run Code Online (Sandbox Code Playgroud)

因此,在您的代码中,如果您正在执行$di = require('di')(path)(没有var),那么您应该能够在其他模块中使用它而不会出现任何问题。使用global.$di可能会使代码更具可读性。