With Spring, you can define an array property and have Spring inject one of every (@Component) class that derives from the given type.
使用Spring,您可以定义一个数组属性,并让Spring注入来自给定类型的每个(@Component)类中的一个。
Is there an equivalent for this in Guice? Or an extension point to add this behavior?
在Guice有类似的东西吗?或者添加这个行为的扩展点?
2 个解决方案
#1
12
This looks like a use case for Guice MultiBinder. You could have something like that:
这看起来像是Guice MultiBinder的用例。你可以有这样的东西:
interface YourInterface {
...
}
class A implements YourInterface {
...
}
class B implements YourInterface {
...
}
class YourModule extends AbstractModule {
@Override protected void configure() {
Multibinder.newSetBinder(YourInterface.class).addBinding().to(A.class):
Multibinder.newSetBinder(YourInterface.class).addBinding().to(B.class):
}
}
And you can inject a Set<YourInterface>
anywhere:
你可以在任何地方插入一个集合 <你的接口> :
class SomeClass {
@Inject public SomeClass(Set<YourInterface> allImplementations) {
...
}
}
That should match with what you need.
那应该和你需要的相符。
#2
7
Guice Multibindings require you to explicitly addBinding() for A
& B
to YourInterface
. If you would like a more "transparent" (automatic) solution such as what AFAIK Spring offers out-of-the-box, then assuming that Guice already knows about A
& B
because you already have a binding for A
& B
elsewhere anyway, even if not explicit but just implicit e.g. through an @Inject
somewhere else, then and only then you alternatively could use something like this for auto-discovery (inspired by as done here, based on accessing Guice injector in a Module):
Guice多绑定要求您将A和B显式地添加到接口中。如果你想更“透明”(自动)解决方案,如春季AFAIK提供开箱即用的,那么假设Guice已经知道a和B为a和B,因为你已经有一个绑定其他地方无论如何,即使没有明确的只是隐如通过@ inject别的地方,然后,只有你或者可以使用这样的自动发现(灵感来自这里,基于访问Guice注入器模块):
class YourModule extends AbstractModule {
@Override protected void configure() { }
@Provides
@Singleton
SomeClass getSomeClass(Injector injector) {
Set<YourInterface> allYourInterfaces = new HashSet<>();
for (Key<?> key : injector.getAllBindings().keySet()) {
if (YourInterface.class.isAssignableFrom(key.getTypeLiteral().getRawType())) {
YourInterface yourInterface = (YourInterface) injector.getInstance(key);
allYourInterfaces.add(yourInterface);
}
return new SomeClass(allYourInterfaces);
}
}
Note again that this approach does NOT require any classpath scanning; it just looks at all already known bindings in the Injector for anything that IS-A YourInterface
.
再次注意,这种方法不需要任何类路径扫描;它只会检查注入器中所有已知的绑定——你的接口。
#1
12
This looks like a use case for Guice MultiBinder. You could have something like that:
这看起来像是Guice MultiBinder的用例。你可以有这样的东西:
interface YourInterface {
...
}
class A implements YourInterface {
...
}
class B implements YourInterface {
...
}
class YourModule extends AbstractModule {
@Override protected void configure() {
Multibinder.newSetBinder(YourInterface.class).addBinding().to(A.class):
Multibinder.newSetBinder(YourInterface.class).addBinding().to(B.class):
}
}
And you can inject a Set<YourInterface>
anywhere:
你可以在任何地方插入一个集合 <你的接口> :
class SomeClass {
@Inject public SomeClass(Set<YourInterface> allImplementations) {
...
}
}
That should match with what you need.
那应该和你需要的相符。
#2
7
Guice Multibindings require you to explicitly addBinding() for A
& B
to YourInterface
. If you would like a more "transparent" (automatic) solution such as what AFAIK Spring offers out-of-the-box, then assuming that Guice already knows about A
& B
because you already have a binding for A
& B
elsewhere anyway, even if not explicit but just implicit e.g. through an @Inject
somewhere else, then and only then you alternatively could use something like this for auto-discovery (inspired by as done here, based on accessing Guice injector in a Module):
Guice多绑定要求您将A和B显式地添加到接口中。如果你想更“透明”(自动)解决方案,如春季AFAIK提供开箱即用的,那么假设Guice已经知道a和B为a和B,因为你已经有一个绑定其他地方无论如何,即使没有明确的只是隐如通过@ inject别的地方,然后,只有你或者可以使用这样的自动发现(灵感来自这里,基于访问Guice注入器模块):
class YourModule extends AbstractModule {
@Override protected void configure() { }
@Provides
@Singleton
SomeClass getSomeClass(Injector injector) {
Set<YourInterface> allYourInterfaces = new HashSet<>();
for (Key<?> key : injector.getAllBindings().keySet()) {
if (YourInterface.class.isAssignableFrom(key.getTypeLiteral().getRawType())) {
YourInterface yourInterface = (YourInterface) injector.getInstance(key);
allYourInterfaces.add(yourInterface);
}
return new SomeClass(allYourInterfaces);
}
}
Note again that this approach does NOT require any classpath scanning; it just looks at all already known bindings in the Injector for anything that IS-A YourInterface
.
再次注意,这种方法不需要任何类路径扫描;它只会检查注入器中所有已知的绑定——你的接口。