我有一个公开方法的服务。我有一个该方法的实现,可以聚合相同服务的其他实现的结果。如何通过注入将其他实现的列表注入到聚合实现中?例如:
我有一个特性 <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 )
实施可以汇总其他实施,例如MultipleDictionaryProvider
和OxfordDictionaryAndColorProvider
。
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
都是通过注入构建的。他们在提供字典之外都有一些作用,他们分别构建了一个单例实例,分别为WebsterDictionaryAndShapeProvider
和ColorProvider
。
我想将ShapeProvider
绑定到DictionaryProvider
。我应该怎么做才能使l里面的元素序列符合我的要求? (MultipleDictionaryProvider
后跟OxfordDictionaryAndColorProvider
这个特殊情况)(订单应该很容易更改,并且只需要在一个地方进行更改)
答案 0 :(得分:2)
如果您正在使用Guice,并且您有一个固定的DictionaryProvider
个对象列表,一种简单的方法是简单地将DictonaryProvider
绑定到MultipleDictionaryProvider
,并在您的注入器中实现提供程序方法List[DictionaryProvider]
的模块:
@Provides
def makeProviderList(
oxford: OxfordDictionaryProvider,
webster: WebsterDictionaryProvider): List[DictionaryProvider] =
List(oxford, webster)
Guice将实例化OxfordDictinaryProvider
和WebsterDictionaryProvider
,调用您的提供程序方法,并使用返回的列表实例化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"))