2017-06-30 16 views
1

私はメソッドを公開するサービスを持っています。私は同じサービスの他の実装の結果を集めることができるそのメソッドの実装を持っています。インジェクションを介して他のインプリメンテーションのリストをその集約インプリメンテーションに注入するにはどうすればよいですか?例えば、注入されたインスタンスのリストを注入する

私は形質をDictionaryProviderとし、get(s: String)メソッドを提供します。私のMultipleDictionaryProviderの実装では、他の実装、たとえばOxfordDictionaryAndColorProviderWebsterDictionaryAndShapeProviderを集約できます。

class OxfordDictionaryAndColorProvider (p: Param) extends DictionaryProvider with ColorProvider 
    class WebsterDictionaryAndShapeProvider extends DictionaryProvider with ShapeProvider 

    class MultipleDictionaryProvider( 
     l: List[ DictionaryProvider ] 
    ) 
    { 
      def get(){ /*Sequence of l matters*/ } 
    } 
    extends DictionaryProvider 

両方OxfordDictionaryAndColorProviderWebsterDictionaryAndShapeProvider注射によって構成されています。それらはどちらも辞書を提供する以外の役割を持ち、とにかく構成されたシングルトンインスタンスをそれぞれColorProviderShapeProviderとして持っています。

DictionaryProviderMultipleDictionaryProviderにバインドしたいと思います。私が望むように内部の要素のシーケンスができるように、どうすればいいですか? (この特定のケースではOxfordDictionaryAndColorProviderに続き、この特定のケースではWebsterDictionaryAndShapeProvider)(変更は簡単で、変更は1か所で行う必要があります)

EDIT:私は質問を編集してより明確にしました。

答えて

2

あなたはGuiceのを使用している、とあなたはDictionaryProviderオブジェクトの固定されたリストを持っている場合は、簡単な方法は、単にMultipleDictionaryProviderDictonaryProviderを結合し、そしてList[DictionaryProvider]のためにあなたのインジェクタモジュール内のプロバイダのメソッドを実装することです:

@Provides 
def makeProviderList(
     oxford: OxfordDictionaryProvider, 
     webster: WebsterDictionaryProvider): List[DictionaryProvider] = 
    List(oxford, webster) 

GuiceはOxfordDictinaryProviderWebsterDictionaryProviderをインスタンス化し、プロバイダメソッドを呼び出し、返されたリストでMultipleDictionaryProviderをインスタンス化します。

あなたのプロバイダ関数のシグネチャで特定のクラス名を避けたい場合は、有用な技術は@Namedと、たとえば、注釈付きのタイプを使用することです:

@Provides 
def makeProviderList(
    @Named("oxford") oxford: DictionaryProvider, 
    @Named("webster") webster: DictionaryProvider) = List(oxford, webster) 

このコードはまだdictionary-の多くを含むように思えますが特定の情報、実装クラスは、実際に指定されていない、彼らはこのようにモジュールクラスにバインドする必要があります辞書の数や種類はまだハードコードされている

bind(classOf[DictionaryProvider]) 
    .annotatedWith(Names.named("oxford")) 
    .to(classOf[OxfordDictionaryProvider]) 

。それをより柔軟に、あなたがあなた自身の手でインスタンス化をする必要がある場合には:

bind(Key.get(new TypeLiteral[List[String]](){})) 
    .toInstance(List("oxford", "webster")) 
+0

Iドン:dictListは、実行時に決定することができることを

val dictList = List("oxford", "webster") @Provides def makeProviderList(injector: Injector) = dictList.map(dictName => injector.getInstance( Key.get(classOf[DictionaryProvider], Names.named(dictName)))) 

注、それもこのバインディングを使用して注入することができますパラメータの型がハードコーディングされているのが好きです。彼らは10のいずれかになる可能性があり、私は手動で複数の場所でそれらを変更したくないです。私はちょうど私が使用するものを決める場所でそれらを一度変更したいです。 – 0fnt

+0

さて、プロバイダー関数はあなたが決める場所です。 – lovei

+0

キーは、インジェクターが異なる「DictionaryProvider」インスタンスを作成し、そのためにインジェクターが作成するものを知る必要があるということです。別のアプローチでは、注釈付きの「DictonaryProvider」引数を使用しています(例:'@ Named')、同じ情報を引き続きハードコードしたり、引数リストのインジェクタを要求したり、' getInstance'を呼び出してリスト要素を構築したりします。後者はより自由度が増し、実行時に辞書を選択することさえ可能になります。 – lovei

関連する問題