1. ホーム
  2. node.js

[解決済み】NodeJSで依存性注入は必要ですか、それともどう対処すれば・・・?

2022-04-03 05:38:33

質問

現在、nodejsでいくつかの実験的なプロジェクトを作成しています。私はSpringで多くのJava EEウェブアプリケーションをプログラムしたことがあり、そこでの依存性注入の容易さに感謝しています。

nodeで依存性注入を行うにはどうすればよいのでしょうか?あるいは、必要なのでしょうか?プログラミングスタイルが違うので、置き換えられるコンセプトがあるのでしょうか?

これまでのところ、データベース接続オブジェクトを共有するような簡単な話なのですが、納得のいく解決策は見つかっていません。

どのように解決するのですか?

要するに、C#/Javaのように依存性注入コンテナやサービスロケータは必要ないのです。Node.jsでは、依存性注入コンテナやサービスロケータは必要ありません。 module pattern そのため、コンストラクタやプロパティのインジェクションを行う必要はありません。ただし、それでも可能です。

JSの素晴らしいところは、欲しいものを実現するために、あらゆるものを修正できることです。これはテストするときに便利です。

見よ、私の非常にいい加減な作為的な例を。

MyClass.js :

var fs = require('fs');

MyClass.prototype.errorFileExists = function(dir) {
    var dirsOrFiles = fs.readdirSync(dir);
    for (var d of dirsOrFiles) {
        if (d === 'error.txt') return true;
    }
    return false;
};

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

このように MyClassfs モジュールですか?ShatyemShekhar が言ったように、確かに他の言語と同様にコンストラクタやプロパティインジェクションを行うことができます。しかし、Javascriptでは必要ないのです。

この場合、2つのことを行うことができます。

をスタブすることができます。 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 : (必ず)もっと良い名前を選んでください

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 モジュールになります。

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 パターンを使って依存関係を管理します。これが少しでも役に立てばいいのですが。