在Node.js和ES6中使用Awilix进行依赖注入
总结
我被要求用Node.js创建一个简单的应用程序(从Web API和数据库获取数据,然后将其注册到AWS S3)。由于代码很小,所以我觉得使用TypeScript之类的东西也很麻烦,所以我用ES6写了它。
在实现了原型后,我意识到在完成产品时仍然需要依赖注入。在调查的过程中,我听说awilix很容易使用。
最初的问题是为什么需要DI?
在原型中,我们以以下方式实现了DAO。
const webDAO = require("./net"); // WEB API 通信モジュール
const dbDAO = require("./db"); // DB 操作モジュール
const s3 = require("./s3"); // S3 操作モジュール
module.exports = {
getData1: function(code){
return webDAO.getData(code);
},
getData2: function(type){
return dbDAO.getData(type);
},
putData: function(key, data){
return s3.putObject(key, data);
}
};
使用者的感觉如下。
const dao = require("./dao");
const data1 = dao.getData1("sample");
dao.putData("sampleKey", data1);
所以,这样会带来一些问题。
-
- ローカル環境では S3 じゃなくてファイルに出力したいこともある
-
- ローカル環境ではデータを固定にしたいこともある
- 一連の処理のテストコードを書きたいが、外部リソースに依存していては・・・
所以,轮到 DI 出场了。
我认为Awilix很好的原因所在
在中国,母语中只需要一种选择,使用JS的 DI 框架确实没有决定版,肯定的。
以前我用过 inversifyJS 来使用typescript,但它的JS支持不够好,所以我在寻找其他的选择时发现了 Awilix。
这个看起来很简洁且易于使用。似乎是使用了 ES6 的代理。
将其修正为DI版
※这只是一个样本,所以各方面都比较随意。
因此,我們將在構造函數中接收dao。
const awilix = require('awilix');
const container = awilix.createContainer();
// モックの DAO
function mock() {
const fs = require("fs-extra");
container.registerValue({
dao: {
getData1: function(code){
return [];
},
getData2: function(type){
return [];
},
putData: function(key, data){
return fs.outputFile(`${key}.txt`, data);
}
}
});
}
// プロダクト用の DAO
function prod() {
const dao = require("./dao/dao");
container.registerValue({dao: dao});
}
mock(); // 注:ここを環境によって切り替える。
// prod();
// 以下、使う側
class TestUser {
constructor(opts) {
this.dao = opts.dao; // モックまたはプロダクト用の DAO がインジェクトされる
}
test() {
this.dao.getData1("sample");
}
}
container.registerClass({
testUser: TestUser
});
const testUser = container.resolve("testUser");
testUser.test();
这只是一个样本,所以各种都没有仔细处理。
因为使用方法很容易理解,所以请参考它。
总结
让我们使用 Awilix 来进行可测试的 Node.js 开发吧!