2015/05/09

Android : Dagger

DaggerはSquare製のAndroidに特化された軽量で高速なDI Framework.

@Injectによる依存関係の構築

Google製のGuiceと比べてパフォーマンスが数倍速い
@Injectでアノテートされたクラス間に依存関係をもたせ, ObjectGraphを構築していく.
@Injectのアノテートはメソッドとフィールドに対して有効.

class CoffeeMaker {
  @Inject Heater heater;
  ...
}

class Thermosiphon implements Pump {
  private final Heater heater;

  @Inject
  Thermosiphon(Heater heater) {
    this.heater = heater;
  }
  ...
}

まずHeaderへの@InjectアノテートによりHeaderの引数なしコンストラクタが呼ばれてインスタンス化される.
Thermosiphonクラスも@Injectでアノテートされた引数にHeaderを受け取るコンストラクタを持つ.
ObjectGraphはこれらのクラス間に依存性を持たせ, Thermosiphonのコンストラクタに先ほど@InjectアノテートされたHeaterインスタンスを渡す.

@Providesによる依存性の提供

@injectアノテーションでは次のことができない.

  • インタフェースを生成できない.
  • 3rdParty製のクラスをアノテートできない.
  • 初期化・構築されたオブジェクトを返却できない.

これらの機能を設けたい場合は@Providesアノテーションを使える.

下記はHeaterの要求に対してElectricHeaderを返す. つまりインタフェースを依存性として注入できる.

@Provides Heater provideHeater() {
  return new ElectricHeater();
}

3rdParty製のクラスに対して@Injectアノテートを付けることはできない.
@Providesを使えば3rdParty製クラスを返却するprovideメソッドを作ることでこれを実現できる.
またセットアップ済みのインスタンスをprovideしたい場合があるかもしれない. この場合にも@Provideは有効に作用する.

制約として, @Providesアノテーションメソッドを持つクラスは@Moduleアノテートされている必要がある.

この他にも多くのオプションがDaggerには備わっている.