[JavaScript] Dependency Injectionコンテナどれにしよう?
Azure FunctionsをJavaScriptで書いていました。
テストを書くにあたり、やっぱり依存先クラスを自前でnewしてるのは辛いなと思い、DIコンテナを探すことにしました。
awilix
https://www.npmjs.com/package/awilix
こちら nodejs, ES6 で dependency injection with awilix で紹介されていました。
コンテナを作り
const container = awilix.createContainer({
injectionMode: awilix.InjectionMode.PROXY
})
コンテナにクラスを登録し
container.register({
userController: awilix.asClass(UserController)
})
コンテナからインスタンスを取り出して使います。
var userController = container.resolve('userController');
簡単です。
依存関係を直接書かなくても解決してくれるのかな?いいですね。
InversifyJS
https://github.com/inversify/InversifyJS
こちら InversifyJSで学ぶDI(Dependency Injection) で紹介されていました。
クラスを修飾し
inversify.decorate(inversify.injectable(), Katana);
inversify.decorate(inversify.injectable(), Shuriken);
inversify.decorate(inversify.injectable(), Ninja);
依存関係を登録し(引数の0や1は、多分コンストラクタ引数の順番)
inversify.decorate(inversify.inject("Katana"), Ninja, 0);
inversify.decorate(inversify.inject("Shuriken"), Ninja, 1);
コンテナを作成し
var container = new inversify.Container();
型名とクラスを紐付け
container.bind("Ninja").to(Ninja);
container.bind("Katana").to(Katana);
container.bind("Shuriken").to(Shuriken);
コンテナからインスタンスを取り出して使います。
var ninja = container.get("Ninja");
だいぶ冗長ですね。安全のために仕方ないみたいです。
TypeScriptだとデコレータがあるのでよい感じです。
bottlejs
https://github.com/young-steveo/bottlejs
こちら bottlejsでDIを試す で紹介されていました。
コンテナを作成し
var bottle = new Bottle();
コンテナに型名とクラスを登録し
bottle.service('Barley', Barley);
bottle.service('Hops', Hops);
bottle.service('Water', Water);
コンテナに依存関係を登録し
bottle.service('Beer', Beer, 'Barley', 'Hops', 'Water');
コンテナからインスタンスを取り出して使います。
var beer = bottle.container.Beer
シンプルですね。
コードサンプルがいい(笑)
その他
npmjs探すといっぱいありますね。
- Aurelia のDIコンテナ部分
- Deep Framework のDIコンテナ部分
結論
それなりのチームであればinversifyJS、少人数and/of小規模ならawilixかbottlejsがよさそうです。
ところで、探してはみたけれど、Azure FunctionsでDIコンテナ使うのはごしたい感じ。