2013-06-07 11 views
5

साथ कई वस्तुओं बाइंडिंग मैं निम्नलिखित कोड Guice बाइंडिंग का उपयोग कर:Guice: विभिन्न निर्भरता

public class MyApplication { 
    public static void main(String[] args) { 
     Guice.createInjector(new AbstractModule() { 
      @Override 
      protected void configure() { 
       bind(Foo.class).annotatedWith(Names.named("first")).toInstance(new Foo("firstFoo")); 
       bind(Foo.class).annotatedWith(Names.named("second")).toInstance(new Foo("secondFoo")); 

       bind(Bar.class).to(BarImpl.class); 

       bind(MyApplication.class).asEagerSingleton(); 
      } 
     }); 
    } 

    private @Named("first") Bar first; 
    private @Named("second") Bar second; 

    static @Value class Foo { String name; } 
    static interface Bar {} 

    static class BarImpl implements Bar { 
     @Inject @Named Foo foo; 
    } 
} 

मैं दोनों का नाम Foo अपने आवेदन में इंजेक्शन रों के लिए एक Bar वस्तु पाने के लिए कोशिश कर रहा हूँ। असल में, इसे किसी भी तरह @NamedFoo पर Bar पर कनेक्ट करना चाहिए। मैंने कस्टम Provider लिखने के लिए सबकुछ पर @Named डालने से कई समाधानों का प्रयास किया है। उत्तरार्द्ध काम नहीं करता क्योंकि मेरे पास प्रदाता के अंदर @Named एनोटेशन के मूल्य तक पहुंच नहीं है। मुझे लगता है कि समाधान bind(Bar.class).to(BarImpl.class); लाइन में कहीं है, इसे @Named एनोटेशन के मान को याद रखने के लिए कह रहा है।

मेरा सवाल है, क्या यह संभव है, और यदि हां, तो कैसे?

उत्तर

10

यह PrivateModules का उपयोग कर रहा है। असल में:

एक निजी मॉड्यूल की कॉन्फ़िगरेशन जानकारी डिफ़ॉल्ट रूप से इसके वातावरण से छिपी हुई है। केवल बाइंडिंग जो स्पष्ट रूप से सामने आती हैं, अन्य मॉड्यूल और इंजेक्टर के उपयोगकर्ताओं के लिए उपलब्ध होंगी। अधिक स्पष्टीकरण के लिए this FAQ entry देखें।

protected void configure() { 
    install(new PrivateModule() { 
     @Override 
     protected void configure() { 
      // #bind makes bindings internal to this module unlike using AbstractModule 
      // this binding only applies to bindings inside this module 
      bind(Foo.class).toInstance(new Foo("first")); 
      // Bar's foo dependency will use the preceding binding 
      bind(Bar.class).annotatedWith(Names.named("first")).to(BarImpl.class); 
      // if we'd stop here, this would be useless 
      // but the key method here is #expose 
      // it makes a binding visible outside as if we did AbstractModule#bind 
      // but the binding that is exposed can use "private" bindings 
      // in addition to the inherited bindings    
      expose(Bar.class).annotatedWith(Names.named("first")); 
     } 
    }); 
    install(new PrivateModule() { 
     @Override 
     protected void configure() { 
      bind(Foo.class).toInstance(new Foo("second")); 
      bind(Bar.class).annotatedWith(Names.named("second")).to(BarImpl.class); 
      expose(Bar.class).annotatedWith(Names.named("second")); 
     } 
    }); 
     bind(MyApplication.class).asEagerSingleton(); 
    } 
} 

अब आप को प्रभावी ढंग से 2 बार्स जिनमें से प्रत्येक की तरह

static class BarImpl implements Bar { 
    @Inject Foo foo; 
} 

लग रही है लेकिन PrivateModules की शक्ति के साथ के लिए बाध्य एक अलग कार्यान्वयन है:

यहाँ कैसे आप इसका उपयोग है एक ही निर्भरता।

आशा है कि यह समझ में आता है।

+0

धन्यवाद, यह आशाजनक लग रहा है। मैं सोमवार को इसे आजमाउंगा। – Jorn

+1

हां, इसने मेरी समस्या हल की। एक बार फिर धन्यवाद! – Jorn

+0

आपका स्वागत है! –

संबंधित मुद्दे