GuiceのモジュールにInjectする方法

Guiceモジュールにはインジェクトできない。

Guiceのモジュールでは、そのconfigure内にバインディングを指定するようになっているのだが、この時点ではインジェクタが作成されていないために、何のオブジェクトもインジェクトできない。例えば、

public class MyModule extends AbstractModule {
  @Inject Foo foo; // インジェクトされない
  public void configure() {
  }
}

これは当たり前だ。そもそもインジェクトするにはインジェクタが必要で、インジェクタを作るための設定がモジュールなのだから。

問題

これをやりたい理由というのは、こうだ。

  • あるライブラリAがある。この中でGuiceをバリバリに使っている。
  • Aを使うアプリBがある。Aの初期化時にB特有の設定をモジュールとして送り込みたい。
  • さらにA内のモジュールの動きをそれで変更したい。

ということだ。

つまり、こうしたい。A側で提供されるのは以下。

public interface Setting {
  様々な設定を取得するインターフェース
}

public class AModule extends AbstractModule {
  @Inject Setting setting;
  public void configure() {
    ... ここでsettingの内容を使う
  }
}

B側はこうだ。

public class SettingImpl implements Setting {
  具体的な設定
}
public class BModule extends AbstractModule {
  public void configure() {
    // A内の具体的設定を指定する
    bind(Setting.class).to(SettingImpl.class).in(Singleton.class);
  }
}

子インジェクタを使う

子インジェクタを使うのが最も簡単ということがわかった。A側はこうなる。

// 最初にBのモジュールを作成してしまう
parent = Guice.createInjector(new BModule());

// 次にAのモジュールを作成する
child = parent.createChildInjector(parent.getInstance(AModule.class));

あとはparentは不要になる。このchildのみを使い回せばよい。

その他の方法

調査したところでは、モジュール内で@Providesを使いプロバイダーを提供するというものがあるのだが、この方法が今回の目的に沿うものかは検証していない。以下に参考URLを載せる。