注入一个注入实例列表
Inject a list of injected instances
我有一个公开方法的服务。我有一个该方法的实现,可以聚合同一服务的其他实现的结果。如何通过注入将其他实现列表注入到聚合实现中?例如:
我有一个特性 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
绑定到 MultipleDictionaryProvider
。我应该怎么做才能使 l 里面的元素顺序可以如我所愿? (对于这种特殊情况,OxfordDictionaryAndColorProvider
后跟 WebsterDictionaryAndShapeProvider
)(顺序应该很容易更改,并且只需要在一个地方更改)
编辑:我对问题进行了编辑以使其更清楚。
如果您使用的是 Guice,并且您有一个固定的 DictionaryProvider
对象列表,一个简单的方法是简单地将 DictonaryProvider
绑定到 MultipleDictionaryProvider
,并在List[DictionaryProvider]
:
的注入器模块
@Provides
def makeProviderList(
oxford: OxfordDictionaryProvider,
webster: WebsterDictionaryProvider): List[DictionaryProvider] =
List(oxford, webster)
Guice 将实例化 OxfordDictinaryProvider
和 WebsterDictionaryProvider
,调用您的提供程序方法,并使用返回的列表实例化 MultipleDictionaryProvider
。
如果您想避免在提供者函数签名中使用特定的 class 名称,一个有用的技术是使用带注释的类型,例如 @Named
:
@Provides
def makeProviderList(
@Named("oxford") oxford: DictionaryProvider,
@Named("webster") webster: DictionaryProvider) = List(oxford, webster)
虽然这段代码似乎仍然包含很多特定于字典的信息,但实际上并未指定实现 classes,它们需要像这样绑定在模块 class 中:
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"))
我有一个公开方法的服务。我有一个该方法的实现,可以聚合同一服务的其他实现的结果。如何通过注入将其他实现列表注入到聚合实现中?例如:
我有一个特性 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
绑定到 MultipleDictionaryProvider
。我应该怎么做才能使 l 里面的元素顺序可以如我所愿? (对于这种特殊情况,OxfordDictionaryAndColorProvider
后跟 WebsterDictionaryAndShapeProvider
)(顺序应该很容易更改,并且只需要在一个地方更改)
编辑:我对问题进行了编辑以使其更清楚。
如果您使用的是 Guice,并且您有一个固定的 DictionaryProvider
对象列表,一个简单的方法是简单地将 DictonaryProvider
绑定到 MultipleDictionaryProvider
,并在List[DictionaryProvider]
:
@Provides
def makeProviderList(
oxford: OxfordDictionaryProvider,
webster: WebsterDictionaryProvider): List[DictionaryProvider] =
List(oxford, webster)
Guice 将实例化 OxfordDictinaryProvider
和 WebsterDictionaryProvider
,调用您的提供程序方法,并使用返回的列表实例化 MultipleDictionaryProvider
。
如果您想避免在提供者函数签名中使用特定的 class 名称,一个有用的技术是使用带注释的类型,例如 @Named
:
@Provides
def makeProviderList(
@Named("oxford") oxford: DictionaryProvider,
@Named("webster") webster: DictionaryProvider) = List(oxford, webster)
虽然这段代码似乎仍然包含很多特定于字典的信息,但实际上并未指定实现 classes,它们需要像这样绑定在模块 class 中:
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"))