2011-07-08 21 views
6

के साथ गुइस के रोबोट-पैरों का उदाहरण सामान्य करें मेरे पास यह उपयोग केस है जो गुइस के रोबोट-पैर उदाहरण के समान है, सिवाय इसके कि मुझे नहीं पता कि मेरे पास कितने "पैर" हैं। इसलिए मैं रोबोट-पैरों के उदाहरण के लिए आवश्यक एनोटेशन का उपयोग नहीं कर सकता।मल्टीबाइंडिंग

मैं इन सभी "पैरों" को java.util.Set में गिस के मल्टीबिंडिंग एक्सटेंशन के साथ इकट्ठा करने की उम्मीद करता हूं।

तकनीकी रूप से, एक निजी मॉड्यूल में मैं एक कार्यान्वयन का पर्दाफाश करना चाहता हूं जो सेट के तत्व के रूप में सीधे मल्टीबिंडिंग एक्सटेंशन द्वारा प्रदान किया जाएगा। मुझे नहीं पता कि यह कैसे करना है।

संदर्भ और कोड उदाहरण के लिए, रोबोट-पैर यहाँ उदाहरण देखें:

मैं निम्नलिखित है:

// 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); 
    } 
} 

के बाद से http://code.google.com/p/google-guice/wiki/FrequentlyAskedQuestions#How_do_I_build_two_similar_but_slightly_different_trees_of_objec


यहाँ मेरी सटीक उपयोग-मामला है मैं विस्तार जार के बारे में बात कर रहा हूं, मैं उन्हें पहले नहीं जानता, मुझे यह भी नहीं पता कि उनमें से कितने मौजूद हैं: मुझे एसके साथ लोड करने की आवश्यकता हैऔर प्रत्येक मॉड्यूल को 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 एक अंतरफलक है कि फैली हुई है की अनुमति देता है:


समाधान, पूरी तरह से जेसी के जवाब पर आधारित मॉड्यूल।

उत्तर

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); 
    } 
} 

इस तरीके को आवश्यक है, क्योंकि multibindings उच्च-स्तरीय इंजेक्टर पर होने की जरूरत है। लेकिन निजी मॉड्यूल बाइंडिंग उस इंजेक्टर के लिए दृश्यमान नहीं हैं, इसलिए आपको उन्हें बेनकाब करने की आवश्यकता है।

+0

धन्यवाद जेसी, हालांकि आपका जवाब पढ़ने के बाद, मुझे यकीन नहीं था कि मैंने समस्या को सही ढंग से समझाया है। तो मैंने एक उदाहरण के साथ अपने प्रश्न को सही किया। क्या यह अब और समझ में आता है? –

+0

ठीक है, मैं आपके नए उत्तर का परीक्षण करूंगा और परिणाम यहां रिपोर्ट करूंगा। –

+0

हां, यह पूरी तरह से काम करता है। इसे मॉड्यूलरिज़ेबल बनाने में काफी मुश्किल है, लेकिन यह ठीक है। –