在node.js中使用全局variables进行dependency injection

我正在开始一个基于node.js的长期项目,所以我正在build立一个坚实的DI系统。 尽pipenode.js的核心意味着使用简单模块require()来连接组件,但是我发现这种方法并不适合于大型项目(例如,要求每个文件中的模块不是可维护,可testing或dynamic的)。

现在,在发布这个问题之前,我已经完成了一些研究工作,并且发现了一些有趣的用于node.js的DI库(参见wire.js , dependable.js )

但是,为了最大限度地简化和最小的重复,我提出了自己的实现DI的build议:

  • 你有一个模块,di.js,作为容器,并通过指向一个json文件来存储一个依赖名称和他们各自的.js文件的地图初始化。 这已经为DI提供了dynamic性,因为您可以轻松地交换testing/ dev依赖关系。 容器可以通过使用一个inject()函数来返回依赖关系,该函数find依赖关系映射并用它调用require()。

  • 为了简单起见,模块被分配到一个全局variables,即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]); } }; }; 

依赖关系图json文件:

 { "vehicle": "lib/jetpack", "fuel": "lib/benzine", "octane": "lib/octane98" } 

根据开发/testing模式,初始化主js文件中的$ di:

 var path = 'dep-map-' + process.env.NODE_ENV + '.json; $di = require('di')(path); 

在一些文件中使用它:

 var vehicle = $di.inject('vehicle'); vehicle.go(); 

到目前为止,我能想到的唯一的问题是全局variables$ di; 据推测,全局variables是一个不好的做法,但在我看来,就像我为单个全局variables的成本节省了大量的重复。

任何人都可以看看我的build议,并build议反对吗?

谢谢!

总的来说,这听起来很好。

全局variables在节点中的工作方式是,当声明一个没有var关键字的variables时,它将被添加到所有模块共享的全局对象中。 你也可以显式使用global.varname 。 例:

 vehicle = "jetpack" fuel = "benzine" console.log(vehicle) // "jetpack" console.log(global.fuel) // "benzine" 

var声明的variables只会在模块本地。

 var vehicle = "car" console.log(vehicle) // "car" console.log(global.vehicle) // "jetpack" 

所以在你的代码中,如果你正在做$di = require('di')(path) (没有var ),那么你应该可以在其他模块中使用它,没有任何问题。 使用global.$di可能会使代码更具可读性。

你的方法是清楚和简单的,这是很好的。 无论您是全局variables还是每次都需要您的模块并不重要。

关于可testing性,它允许你用模拟来replace你的模块。 对于unit testing,您应该添加一个函数,使您可以轻松地为每个testing应用不同的模拟。 东西,暂时扩展您的依赖关系图。

为了进一步阅读,我可以推荐一篇很棒的关于node.js中dependency injection的博客文章,以及由一些严肃的策划者devise的angular.js的未来dependency injection器 。

顺便说一下,你可能会对Fire Up感兴趣! 这是我实现的dependency injection容器。