2017-06-30 56 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

我想將我的DictionaryProvider綁定到MultipleDictionaryProvider。我應該怎麼做才能讓我內部的元素序列可以像我想要的那樣? (OxfordDictionaryAndColorProvider其次爲WebsterDictionaryAndShapeProvider對於這種特殊情況)(訂單應該很容易改變,只需要在一個地方更改)

編輯:我編輯了一個問題,使其更清晰。

回答

2

如果您正在使用吉斯,你有DictionaryProvider對象的固定列表,一個簡單的方法是簡單地綁定DictonaryProviderMultipleDictionaryProvider,並實施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]) 

詞典的數量和種類仍然硬編碼。爲了讓更多的靈活性,你將需要採取實例在自己的手中:

val dictList = List("oxford", "webster") 

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

注意dictList可以在運行時確定的,它甚至可能被注射使用此綁定:

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

我不不喜歡參數類型是硬編碼的。他們可以是10箇中的任何一個,我不想在多個地方手動更改它們。我只是想在我決定使用哪一個的地方改變它們一次。 – 0fnt

+0

那麼,提供者函數是你決定的唯一地方:) – lovei

+0

關鍵是你想讓注入器創建不同的'DictionaryProvider'實例,爲此,注入器必須知道要創建哪些實例。其他方法使用帶註釋的'DictonaryProvider'參數(例如'@ Named'),它仍然對相同的信息進行硬編碼,或者在參數列表中詢問一個注入器並通過調用'getInstance'來構造列表元素。後者會給你更多的自由,甚至可以在運行時選擇字典。 – lovei