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