くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

AndroidとDagger2でDIしてみる

前々から気になっていたDIライブラリのDaggerを使ってみたので、その備忘録。

登場人物はこんな感じ

DIといえば、Springな人なので、イメージを掴むのが一苦労だった。。

全体像がよくわからないので、図にしてみた。

こんな感じ。

f:id:wannabe-jellyfish:20170730214305p:plain

使い方

build.gradleのdependenciesに依存関係を追加すればOK

dependencies {
    // Dagger
    compile 'com.google.dagger:dagger:2.11'
    annotationProcessor 'com.google.dagger:dagger-compiler:2.11'
    provided 'javax.annotation:jsr250-api:1.0'
}

各登場人物のTips

@Inject

コンストラクタインジェクションもできる

public class Sample {
  @Inject
  public Sample(Aclass aCls) {
    // aClsがInjectionされてSampleクラスのインスタンスを生成
  }
}

@Provide

具象クラスであれば、@Provideはいらない

具象クラスが特定できるオブジェクトは、@Provideのメソッドが不要(DIする意味ないかもしれないが。。。)

インターフェースを切っていたり、アブストラクトクラスに対して@Injectを付与している場合は必要

@Provideのメソッドも引数が取れる

こんな感じ。ただし、引数に渡すクラスの@Provideが用意されている必要がある

@Module
public class AppModule {
  @Provide
  public Aclass provideAclass(Bclass bCls) {
     return ・・・
  }

  @Provide
  public Bclass provideBclass() {
    //これがprovideAclass()で使われる
  }
}

@Module

@Moduleのついたクラスにコンストラクタ引数が使える

こんな感じ。

@Module
public class AppModule {
  public AppModule(ArgClass argCls) {
  }
}

ただし、Componentを生成するときに引数を指定が必要

public class MainClass {
  public MainClass() {
    DIComponent diComponent = DaggerDIComponent
      .builder()
      .appModule(new AppModule(this))  // <- ここで指定
      .build();
  }
}

デフォルトコンストラクタのみの@Moduleのクラスだと、builder()でModuleの指定を省略できる

@Component

@Componentで用意するのは、エントリーポイントとなるクラスだけ

例えば、こんな感じ担っている場合。

public class Aclass() {
  @Inject Bclass bCls;
}

public class Bclass() {
  @Inject Cclass cClas;
}

Aclassに対する@ComponentがあればOK。指定したクラスを起点に、内部のフィールドを辿ってくれる。

以上!!

参考にしたサイト様