我目前使用nodejs创建一些实验项目。我已经用Spring编写了很多Java EE Web应用程序,并赞赏那里的依赖注入的简易性。
现在我很好奇:如何使用节点进行依赖注入?或者:我什至需要吗?是否存在替代概念,因为编程风格不同?
到目前为止,我在谈论简单的事情,例如共享数据库连接对象,但是我还没有找到一个令我满意的解决方案。
简而言之,您不需要像C#/ Java中那样的依赖项注入容器或服务定位器。由于Node.js利用module pattern,因此无需执行构造函数或属性注入。虽然您仍然可以。
module pattern
JS的伟大之处在于,您可以修改几乎所有内容以实现所需的功能。在进行测试时,这很方便。
看我非常very脚的人为例子。
MyClass.js:
MyClass.js
var fs = require('fs'); MyClass.prototype.errorFileExists = function(dir) { var dirsOrFiles = fs.readdirSync(dir); for (var d in dirsOrFiles) { if (d === 'error.txt') return true; } return false; };
MyClass.test.js:
MyClass.test.js
describe('MyClass', function(){ it('should return an error if error.txt is found in the directory', function(done){ var mc = new MyClass(); assert(mc.errorFileExists('/tmp/mydir')); //true }); });
注意如何MyClass依赖fs模块?正如@ShatyemShekhar所提到的,您确实可以像使用其他语言一样进行构造函数或属性注入。但这在Javascript中不是必需的。
MyClass
fs
在这种情况下,您可以做两件事。
您可以对fs.readdirSync方法进行存根,也可以在调用时返回完全不同的模块require。
fs.readdirSync
require
方法1:
var oldmethod = fs.readdirSync; fs.readdirSync = function(dir) { return ['somefile.txt', 'error.txt', 'anotherfile.txt']; }; *** PERFORM TEST *** *** RESTORE METHOD AFTER TEST **** fs.readddirSync = oldmethod;
方法2:
var oldrequire = require require = function(module) { if (module === 'fs') { return { readdirSync: function(dir) { return ['somefile.txt', 'error.txt', 'anotherfile.txt']; }; }; } else return oldrequire(module); }
关键是利用Node.js和Javascript的功能。请注意,我是CoffeeScript专家,所以我的JS语法在某处可能不正确。另外,我并不是说这是最好的方法,而是一种方法。Javascript专家可能会与其他解决方案配合使用。
更新:
这应该解决您有关数据库连接的特定问题。我将为您创建一个单独的模块,以封装您的数据库连接逻辑。像这样:
MyDbConnection.js:(请务必选择一个更好的名称)
MyDbConnection.js
var db = require('whichever_db_vendor_i_use'); module.exports.fetchConnection() = function() { //logic to test connection //do I want to connection pool? //do I need only one connection throughout the lifecyle of my application? return db.createConnection(port, host, databasename); //<--- values typically from a config file }
然后,任何需要数据库连接的MyDbConnection模块都将仅包含您的模块。
MyDbConnection
SuperCoolWebApp.js:
SuperCoolWebApp.js
var dbCon = require('./lib/mydbconnection'); //wherever the file is stored //now do something with the connection var connection = dbCon.fetchConnection(); //mydbconnection.js is responsible for pooling, reusing, whatever your app use case is //come TEST time of SuperCoolWebApp, you can set the require or return whatever you want, or, like I said, use an actual connection to a TEST database.
不要逐字遵循此示例。在尝试传达您利用module模式来管理依赖项时,这是一个la脚的例子。希望这会有所帮助。
module