モバイルペイメント事業のSquareはDaggerという新しいライブラリを発表した。このライブラリは"AndroidとJava向けの高速な依存性注入機構"を提供する。ソースコードはGitHubから入手できる。
依存性注入(制御の反転としても知られている)はSpringやGoogle Guiceのような人気のフレームワークでは既に導入されている。しかし、これらのフレームワークは標準的なJVMを対象にして作られており、Androidのようなモバイル環境では使えない。RoboGuiceはAndroid上でのGuiceの利用を改善する試みだが、Daggerは仕組みをシンプルにしてパフォーマンスを追求している。
Daggerがサポートするのは、
- JSR-330の標準的なアノテーションを利用したコンストラクタインジェクション
- @Providesアノテーションを使ったオブジェクトの生成
- 依存性ツリーのための中心的なコンテキスト
- 高価なリソースのための遅延インジェクション
- 同じインターフェイスの異なる実装のための量指定子
- 静的インジェクション(レガシな環境向け)
- コンパイル時のバインディングの検証
Daggerは最も基本的なレベルで、SpringとGuiceで使われている標準のインジェクトアノテーションをサポートする。メソッドは注入できない。Guiceと同じように動作する@Providesアノテーションを提供する。
依存が定義されると、依存を解決するクラスが、初期化されたオブジェクトのツリーを保持するObjectGraph経由で取得できる。ObjectGraphの挙動はSpringのApplicationContextやGuiceのInjectorと同じだ。また、DaggerはGuiceと同様にModules(バインディングのコレクション)の概念もある。
コネクションプールのような依存性は作成するのに高いコストがかかる。このような場合のためにDaggerは遅延インジェクションをサポートする。構文もGuiceに似ている。同一の仕様に対して複数の実装がある場合に備えて、Daggerは@Namedアノテーションの規約に従う。
そして、依存性注入の代わりにファクトリを使っているようなレガシなコードの注入もサポートする。これも構文や使い方はGoogle Guiceと似ている。
今のところ、DaggerがサポートするのはGoogle Guiceの一部の機能に過ぎないようだ。DaggerとGoogle Guiceの開発関係者が重複していると考えるのは不思議ではない。しかし、Daggerは小さなフレームワークで明らかにAndroidを念頭に実装されている。最も大きい違いはメソッドとフィールドの注入ができないことだ。
Daggerはこれらの機能を犠牲にしてエラーの検出を改善している。普通、依存性注入のエラーはアプリケーションの実行時にしかわからない。しかし、Daggerはコンパイル時にアノテーションの検証をし、不正なバインディングをコンパイルエラーとして検出する。このおかげでAndroidアプリケーションの開発は楽になる。
また、スコープがないのも他のフレームワークとの大きな違いだ。Daggerがサポートするのは、@Singletonアノテーションだけだ。これもAndroidの開発は標準的なウェブの開発(リクエストとセッションのスコープが必要な)とは異なることを念頭に置いた仕様だ。
また、Springのユーザ向けにDaggerと比べた場合のSpringの欠点についての2つのレポートがある。ひとつはSpringはアノテーションを保持するクラスしか注入できないことに関係しており、もうひとつはジェネリック型があるインターフェイスを実装したクラスを識別できないことに関係している。
現時点ではDaggerのドキュメントはREADMEファイルしかない。コードのライセンスはApache 2ライセンス。まだ正式なリリースはしていない(ソースコードのタグもない)。Daggerを実際に使ってみたい場合はこの点を考慮する必要がある。