DIについて
は、色んな記事が出てると思うので割愛!
超ざっくり言うと、クラスの外からインスタンスを注入して結合度を下げる手法!
インタフェースを用意して、そこに注入してあげるとテストもしやすくなる奴です。
マサカリ大歓迎です!!!
何か認識間違っていたり、足りなかったりしていたら教えてください・・・!
詰まったところ
先にAndroidで導入する際に詰まった点を紹介します。
何に詰まったのか
Gradleで依存の指定方法が足りなかった&現段階で必要のない依存の指定をしていた。
どう間違えたのか
Dagger2公式#How do I get it?
ここに書かれている依存だけ書いてしまって、Javaの依存を書いてなかった。
導入方法
公式より、 GithubのReadMeを見た方が早かった。。
app配下のgradleに以下のコードを追加してsyncします。
dependencies {
...
compile 'com.google.dagger:dagger:2.14.1'
annotationProcessor 'com.google.dagger:dagger-compiler:2.14.1'
}
で、インスタンスを外部から注入できるようになります。
外部の知識(WebAPIなど)や、インフラ層(repository)等を切り分けたい時はこれだけで十分です。
dagger.androidってどんな時に使えるのかまだ調べてないので、良ければ教えて頂きたくm(_ _)m
ざっくりと注入の仕方
Moduleを作って、ComponentにInjectする対象を定義して、 @Inject
を指定するだけ。
フィールドとコンストラクタインジェクションに対応しています。
ModuleはいわゆるDIコンテナ、と捉えていい(はず)です。
インスタンスの生成を別に切り出して、一つの場所で管理するって考え方なので。
まずは、Moduleを作ります。
// suffixにModuleを付けるのがお作法。
@Module
public class InfrastructureModule {
// prefixに provide を付けるのがお作法。
@singleton
@provide
public RepositoryInterafce provideXYZRepository() {
return new XYZRepository();
}
}
こんな感じに書きます。
@Singleton
を指定すると、Daggerが勝手にシングルトンとして生成を扱ってくれます。
次にComponentを作ります。
Componentは、作った任意のModuleをどこに注入するのかを定義するインタフェースです。
こう書きます。
// suffixにComponentを付けるのがお作法。
// singletonなインスタンスを扱うので @Singleton を指定する。じゃないとビルドでエラー吐く。
@Singleton
@Component(Modules = {InfrastructureModule.class})
public class InfrastructureComponent {
// メソッド名はinjectとするのがお作法。お作法だらけだけど慣れれば脳筋プレイできる!w
void inject(FugaHoge fugaHoge);
void inject(FooBar fooBar);
}
あとは @Inject
を付けてフィールドなりコンストラクタなりに注入します。
public class FugaHoge {
// フィールドインジェクションしてみる
@Inject RepositoryInterface repository;
public FugaHoge() {
// Rebuild走らせておくと、prefix:Daggerの、コンポーネント実体が自動生成される。
// コンストラクタ内でinjectさせる。
DaggerInfrastructureComponent.create().inject(this);
}
}
こうするだけで、 repository
にインスタンスが注入されます。
おわり。