我有這個用例非常類似於Guice的機器人腿的例子,除了我不知道我有多少「腿」。因此我不能使用機器人腿示例所需的註釋。概括guice的機器人腿與多重綁定的例子
我期望將所有這些「腿」收集在一個java.util.Set中,並帶有Guice的Multibindings擴展。
從技術上講,在一個PrivateModule中,我想直接將一個實現公開爲Multibindings擴展提供的一組元素。我只是不知道該怎麼做。
參考,代碼示例,請參閱機器人腿例子在這裏: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);
}
}
由於我在談論擴展罐,起初我不認識它們,我甚至不知道它們中有多少個:我需要將MyModule
加載到j.u.ServiceLoader
,每個模塊應該定義一個MyInterface
實現(這兩個部分都可以)。
問題是讓所有的MyInterface
實現在一個集合(在MyManager
)。我怎樣才能做到這一點?
解決方案,完全基於傑西的回答是:
// Create the set binder.
Multibinder<MyInterface> interfaceBinder = Multibinder.newSetBinder(binder(), MyInterface.class, MyBinding.class);
// Load each module that is defined as a service.
for (final MyModule module : ServiceLoader.load(MyModule.class)) {
// Generate a key with a unique random name, so it doesn't interfere with other bindings.
final Key<MyInterface> myKey = Key.get(MyInterface.class, Names.named(UUID.randomUUID().toString()));
install(new PrivateModule() {
@Override protected void configure() {
// Install the module as part of a PrivateModule so they have full hands on their own implementation.
install(module);
// Bind the unique named key to the binding of MyInterface.
bind(myKey).to(MyInterface.class);
// Expose the unique named binding
expose(myKey);
}
});
// bind the unique named binding to the set
interfaceBinder.addBinding().to(myKey);
}
這讓我不強迫「顧客」來擴展PrivateModule,而是使用任何模塊實現,如果MyModule的是擴展的接口模塊。
謝謝傑西,但是在閱讀你的答案後,我不確定我是否正確地解釋了這個問題。所以我用一個例子糾正了我的問題。現在這更容易理解嗎? –
好吧,我會測試你的新答案並在這裏報告結果。 –
是的,它完美的工作。使其變得可模塊化是相當困難的,但沒關係。 –