Sunrabbit

Node.js初心者でも作れるフレームワークレベルDI

作成: 2024-11-08

作成: 2024-11-08 14:02

Node.jsでサーバー開発をしていると、数多くのSpringの誘惑を受けます。

構造化されていて、体系的で、安易に脱獄することが難しいからです。


そのため、Node.js陣営ではNest.jsというフレームワークが誕生しました。

少なくともSpringのように構造化された形でサーバー開発をしたいという、多くの意欲があったのです。


しかし、SpringのDIはランタイムのリフレクションを利用して、言語レベルでDIを実行できるようサポートしています。

Dotnetも同様に、属性に基づいて追跡し、リフレクションでDIを実行します。


それでは、Nest.jsはどのようにDIを実行できたのでしょうか?

SpringとDotnetは基盤となる言語がコンパイラ言語であるため、言語レベルでリフレクションをサポートしていましたが、

ecma scriptはただの…インタープリタ言語の凡夫じゃないですか?


以下は、Nest.jsのチュートリアルにある例の一つです。


明らかに、このようにTypeScriptで書かれたコードはコンパイルされると型タグがすべて削除された形になり、クラスからコンストラクタに必要なargument typeが分からなくなるでしょう。


解決策は言語仕様にありました。

Reflect

幸いにも、言語レベルで各オブジェクトにメタデータを挿入するように作られた機能がありました。

Node.js初心者でも作れるフレームワークレベルDI


単にオブジェクトにメタデータを追加し、取得する単純な機能です。


そこでTypeScriptは考えました。

それでは、クラスをコンパイルする際に型情報をメタデータに入れてみようか?


そこでTypeScriptは、クラスデコレータが付いている箇所に、該当クラスのコンストラクタに必要な引数値の情報をReflectに保存していました。

Node.js初心者でも作れるフレームワークレベルDI

ここには、何らかのトランスフォームや黒魔術は入っておらず、純粋にTypeScriptコンパイラの機能です。


このように、該当クラスのメタデータにコンストラクタに必要な引数値の型が入っていれば、

クラスを読み込んで型が分かるため、そのまま挿入できるようになったのです。


これに関する実装はNestJSを見ても良いですが、これはあまりにも長いため、別のライブラリをお勧めします。


上記のライブラリはMicrosoftが作成したもので、コードがきれいです。

一度見てみることをお勧めします。これにて筆を置きたいと思います。

コメント0