その場バインディング
インジェクタがあるタイプのインスタンスを必要とするとき、バインディングを必要とする。 モジュールで定義されたバインディングのことを明示的バインディングと呼び、インジェクタはそれが提供されている場合はそれを使う。 タイプ(のインスタンス)が必要にも関わらず明示的バインディングが無い場合には、インジェクタは「その場バインディング」を試みる。 これらは、JITバインディングとか暗黙的バインディングなどとも呼ばれる。
コンストラクタバインディング
Guiceは、そのタイプの注入可能なコンストラクタを使うことにより、コンクリートな型に対するバインディングを作成する。 これらは、publicで引数なしのコンストラクタか、@Injectアノテーションのついたコンストラクタである。
public class PayPalCreditCardProcessor implements CreditCardProcessor { private final String apiKey; @Inject public PayPalCreditCardProcessor(@Named("PayPal API key") String apiKey) { this.apiKey = apiKey; }
Guiceはネストされたクラスを作成しない、それらがstaticモディファイア付でない限り。 内部クラスはそのエンクロージングクラスへの暗黙的な参照を持つため、注入不可能である。
@ImplementedBy
アノテーションによって、デフォルトの実装タイプをインジェクタに伝えることができる。 @ImplementedByアノテーションは、サブタイプを指定することによってリンクバインディングのようにふるまう。
@ImplementedBy(PayPalCreditCardProcessor.class) public interface CreditCardProcessor { ChargeResult charge(String amount, CreditCard creditCard) throws UnreachableException; }
上記のアノテーションは以下のbind()と等価である。
bind(CreditCardProcessor.class).to(PayPalCreditCardProcessor.class);
もし、一つのタイプがbind()指定されており、かつ@ImplementedByアノテーションを持つ場合には、bind()が優先する。 アノテーションはデフォルトの実装を指定するものであり、バインディングによってオーバライドすることができる。 @ImplementedByは注意して使うように、なぜならコンパイル時の依存をインターフェースと実装の間にもたらしてしまうからだ。
@ProvidedBy
@ProvidedByはそのインスタンスを作成するプロバイダをインジェクタに通知する。
@ProvidedBy(DatabaseTransactionLogProvider.class) public interface TransactionLog { void logConnectException(UnreachableException e); void logChargeResult(ChargeResult result); }
上記のアノテーションは、以下のtoProvider()バインディングと等価である。
bind(TransactionLog.class) .toProvider(DatabaseTransactionLogProvider.class);
@ImplementedByと同様に、両方ある場合はbind()が優先する。