我的这个用例非常类似于Guice的机器人腿例子,除了我不知道我有多少“腿”。因此,我无法使用机器人腿示例所需的注释。
我希望在带有Guice的Multibindings扩展名的java.util.Set中收集所有这些“leg”。
从技术上讲,在PrivateModule中,我想直接公开一个实现作为Multibindings扩展提供的集合的元素。我只是不知道该怎么做。
有关参考和代码示例,请参阅此处的robot-legs示例:http://code.google.com/p/google-guice/wiki/FrequentlyAskedQuestions#How_do_I_build_two_similar_but_slightly_different_trees_of_objec
这是我的确切用例:
我有以下内容:
// Main application
public interface MyTree {...}
public interface MyInterface {
public MyTree getMyTree() {}
}
public abstract class MyModule extends PrivateModule {}
public class MyManager {
@Inject MyManager (Set<MyInterface> interfaces){ this.interfaces = interfaces }
}
public class MainModule extends AbstractModule {
public void configure () {
// Install all MyModules using java.util.ServiceLoader.
}
}
// In expansion "square.jar"
public class SquareTree implements MyTree {...}
public class SquareImplementation implements MyInterface {
@Inject SquareImplementation (MyTree tree) { this.tree = tree; }
public MyTree getMyTree () { return this.tree; }
}
public class SquareModule extends MyModule { // correctly defined as a ServiceLoader's service.
public void configure () {
// How to make this public IN a multibinder's set?
bind(MyInterface.class).to(SquareImplementation.class);
// Implementation specific to the Squareimplementation.
bind(MyTree.class).to(SquareTree.class);
}
}
// In expansion "circle.jar"
public class CircleTree implements MyTree {...}
public class CircleImplementation implements MyInterface {
@Inject CircleImplementation (MyTree tree) { this.tree = tree; }
public MyTree getMyTree () { return this.tree; }
}
public class CircleModule extends MyModule { // correctly defined as a ServiceLoader's service.
public void configure () {
// How to make this public IN a multibinder's set?
bind(MyInterface.class).to(CircleImplementation.class);
// Implementation specific to the Circle implementation.
bind(MyTree.class).to(CircleTree.class);
}
}
由于我在谈论扩展罐,我起初并不知道它们,我甚至不知道它们中有多少存在:我需要用{{1}加载MyModule
s并且每个模块应该定义一个j.u.ServiceLoader
实现(这两个部分都可以)。
问题是将所有MyInterface
实现集中在一个集合中(MyInterface
中)。我怎么能这样做?
解决方案,完全基于Jesse的回答:
MyManager
这允许我不强制“customer”扩展PrivateModule,而是使用任何模块实现,如果MyModule是扩展Module的接口。
答案 0 :(得分:9)
看起来你需要跳过一些箍来促进来自私有模块的绑定,以便它们可以在顶级注入器的多重绑定中。
这应该有效:
public class SquareModule extends AbstractModule { // does not extend PrivateModule
@Overide public void configure() {
// this key is unique; each module needs its own!
final Key<MyInterface> keyToExpose
= Key.get(MyInterface.class, Names.named("square"));
install(new PrivateModule() {
@Override public void configure() {
// Your private bindings go here, including the binding for MyInterface.
// You can install other modules here as well!
...
// expose the MyInterface binding with the unique key
bind(keyToExpose).to(MyInterface.class);
expose(keyToExpose);
}
});
// add the exposed unique key to the multibinding
Multibinder.newSetBinder(binder(), MyInterface.class).addBinding().to(keyToExpose);
}
}
这种解决方法是必要的,因为多绑定需要在顶级注入器处进行。但是私有模块绑定对于该注入器是不可见的,因此您需要公开它们。