注入注入实例的列表

时间:2017-06-30 16:46:17

标签: java scala dependency-injection guice

我有一个公开方法的服务。我有一个该方法的实现,可以聚合相同服务的其他实现的结果。如何通过注入将其他实现的列表注入到聚合实现中?例如:

我有一个特性 <servlet> <servlet-name>register</servlet-name> <servlet-class>Register</servlet-class> </servlet> <servlet-mapping> <servlet-name>register</servlet-name> <url-pattern>/register</url-pattern> </servlet-mapping> ,提供DictionaryProvider方法。我的get( s: String )实施可以汇总其他实施,例如MultipleDictionaryProviderOxfordDictionaryAndColorProvider

WebsterDictionaryAndShapeProvider

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 OxfordDictionaryAndColorProvider都是通过注入构建的。他们在提供字典之外都有一些作用,他们分别构建了一个单例实例,分别为WebsterDictionaryAndShapeProviderColorProvider

我想将ShapeProvider绑定到DictionaryProvider。我应该怎么做才能使l里面的元素序列符合我的要求? (MultipleDictionaryProvider后跟OxfordDictionaryAndColorProvider这个特殊情况)(订单应该很容易更改,并且只需要在一个地方进行更改)

编辑:我对问题进行了编辑,使其更加清晰。

1 个答案:

答案 0 :(得分:2)

如果您正在使用Guice,并且您有一个固定的DictionaryProvider个对象列表,一种简单的方法是简单地将DictonaryProvider绑定到MultipleDictionaryProvider,并在您的注入器中实现提供程序方法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)

虽然这段代码似乎仍然包含很多特定于字典的信息,但实际上没有指定实现类,它们需要绑定在模块类中,如下所示:

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"))