2

Guiceをレビューしています。次の設定があるとします。

public interface IsEmailer {...}
public interface IsSpellChecker {...}
public class Emailer implements IsEmailer { 
       @Inject
       public class Emailer(final IsSpellChecker spellChecker)....
}
public class FrenchSpellChecker implements IsSpellChecker {....}
public class EnglishSpellChecker implements IsSpellChecker {....}
@BindingAnnotation public @interface English {}
@BindingAnnotation public @interface French {} 

次に、私のモジュールで、インターフェイスをそれぞれの実装にバインドし、それぞれのバインディング アノテーションでスペル チェッカーにアノテーションを付けました。

ここで、ランタイム変数に基づいて、英語またはフランス語のスペル チェッカーを使用する電子メール プログラムを作成する必要があるとします。

モジュールで名前付きプロバイダーを使用することを考えました:

@Provides
@English
IsEmailer provideEnglishEmailer() {
    return new Emailer(new EnglishSpellChecker());
}

@Provides
@French
IsEmailer provideFrenchEmailer() {
    return new Emailer(new FrenchSpellChecker());
}

これは次のように機能します。

IsEmailer emailer = myModule.getInstance(Key.get(IsEmailer.class,
                French.class));

これは、このようなことを行う最もクリーンな方法ですか? 結局のところ、(プロバイダーで) 手でオブジェクトを作成する必要があります。

ありがとう

4

2 に答える 2

2

最初のメモ:

  • getInstance一般に、「ルート」要素 (例: ) を除いて、できるだけ使用を避けたいと考えていますYourApplication。Guice が提供するもののうち、最善の策は、Provider<IsEmailer>、またはおそらく@English Provider<IsEmailer>andの注入を要求することです@French Provider<IsEmailer>getを呼び出すまで、Guice は実際には要素を作成しませんProvider。そのため、作成のオーバーヘッドProviderは非常に軽くなります。

  • プロバイダーを取得するためにプロバイダーにバインドする必要はありません。Guice はX、 、Provider<X>、またはのor@Provides Xのインジェクションへのバインディングを自動的かつ透過的に解決します。XProvider<X>

  • Provider実装は、メソッドと同様に、注入されたパラメーターを取ることができ@Providesます。

  • @English多くのものをorにバインドしたい場合は、プライベート モジュール@Frenchを調査することもできます。これは、私には「ロボットの脚」の問題のように聞こえるためです。

最も簡単な方法はProvider、特にこれを 1 回しか実行しない場合は、最初の箇条書きを使用して、それぞれに a を挿入することです。

ランタイム変数が Guice 経由でアクセスできる場合は、モジュールにバインドすることもできます。@Providesこれを上記の注釈とともにモジュールに入れます。(前述のように、スペル チェッカーが独自の依存関係を挿入できるように、パラメーターとしてそれぞれEnglishSpellCheckerおよびを受け入れるように書き換える必要がある場合があります。)FrenchSpellChecker

@Provides IsEmailer provideEmailer(Settings settings,
    @English Provider<IsEmailer> englishEmailer,
    @French Provider<IsEmailer> frenchEmailer) {
  if (settings.isEnglish()) {
    return englishEmailer.get();
  } else {
    return frenchEmailer.get();
  }
}
于 2013-03-05T22:22:14.693 に答える
1

MapBinderを使用できます。これにより、 を挿入してMap<Language, IsSpellChecker>、実行時に適切なスペル チェッカーを取得できます。

于 2013-03-06T01:45:22.293 に答える