2012-02-11 15 views
28

मैं नीचे के रूप में एक कारखाने के साथ निर्माता के लिए,पास पैरामीटर Guice

public final class Application { 

    private static IFoo foo; 

    public static IFoo getFoo(String bar) 
    { 
      // i need to inject bar to the constructor of Foo 
      // obvious i have to do something, not sure what 
     Injector injector = Guice.createInjector(); 
     logger = injector.getInstance(Foo.class); 
     return logger;    
    } 

} 

यह फू परिभाषा है:

class Foo 
{ 
    Foo(String bar) 
    { 

    } 

} 

ठीक है। मुझे यकीन नहीं है कि मैं इस पैरामीटर को गुइस के साथ फू कन्स्ट्रक्टर में कैसे पारित कर सकता हूं?

कोई विचार?

उत्तर

43

सभी "गिइस कन्स्ट्रक्टर पैरामीटर" उत्तर किसी भी तरह से अपूर्ण प्रतीत होते हैं। यहाँ उपयोग सहित एक पूर्ण समाधान है:

interface FooInterface{ 
    String getFooName(); 
} 

// एनोटेट निर्माता और सहायता प्रदान की मानकों कार्यान्वयन वर्ग पर

class Foo implements FooInterface { 
    String bar; 

    @Inject 
    Foo(@Assisted String bar) 
    { 
     this.bar = bar; 
    } 

    // return the final name 
    getFooName(){ 
    return this.bar; 
    } 

} 

// एक विधि create() कि लेता है के साथ एक कारखाना इंटरफ़ेस बनाएँ केवल सहायक पैरामीटर। // FooFactory इंटरफ़ेस एक स्पष्ट कार्यान्वयन वर्ग (Guice जादू)

interface FooFactory{ 
    Foo create(String bar); 
} 

// एक प्रदाता AssistedInject

द्वारा बनाई
binderModule implements Module{ 

void configure(Binder binder) { 
    binder.install(new FactoryModuleBuilder() 
     .implement(FooInterface.class, Foo.class) 
     .build(FooFactory.class)); 
} 
} 

है कि कारखाने में आबद्ध नहीं है // अब इसका इस्तेमाल:

class FooAction{ 

    @Inject private FooFactory fooFactory; 

    doFoo(){ 
     // Send bar details through the Factory, not the "injector" 
     Foo f = fooFactory.create("This foo is named bar. How lovely!"); 
     f.getFooName(); // "This foo is named bar. How lovely!" 
    } 
} 

बहुत से यहाँ मदद करता है: https://google.github.io/guice/api-docs/latest/javadoc/index.html?com/google/inject/assistedinject/FactoryModuleBuilder.html

+0

मेरे लिए काम नहीं करता है। मेरे पास * NullPointerException * है * क्योंकि * फू * कन्स्ट्रक्टर कभी नहीं बुलाया गया। शायद आपको अपने * मॉड्यूल * कहीं भी उपयोग करने की ज़रूरत है? –

+0

कृपया "निर्माण" विधि (FooFactory इंटरफ़ेस) के लापता वापसी प्रकार को ठीक करें। यह होना चाहिए: फू बनाएँ (स्ट्रिंग बार); – frhack

1

तो इस वर्ग के एक कारखाने है, यह एक Guice से प्रबंधित ऑब्जेक्ट होना चाहिए, एक गैर स्थिर getFoo विधि है, और हर वर्ग Guice द्वारा instantiated किए जाने की आवश्यकता getFoo विधि सिर्फ

new Foo(bar) 

का प्रयोग करेंगे ।

इस कारखाने को स्वयं बनाने से बचने के लिए AssistedInject भी देखें और गुइस को आपके लिए एक बनाएं।

8

जो आप शायद खोज रहे हैं वह एक गिवाइस कारखाना का उपयोग करना है। AssistedInject कार्यक्षमता के साथ विशेष रूप से आसान है, लेकिन उनके पास manual example at the top of the page है। मैन्युअल उदाहरण के लिए इसका संक्षेप यह है कि आप गैर-स्थैतिक getFoo विधि के तहत कारखाना प्राप्त करते हैं, जिसे आप जिस भी पैरामीटर की आवश्यकता है उसे पास करते हैं और वहां से ऑब्जेक्ट बनाते हैं।

यदि आपके पास Foo में विधि अवरोध है तो यह सीधे काम नहीं करेगा, लेकिन यह कई अन्य मामलों में काम करेगा।

AssistedInject उपयोग करने के लिए, जो मेरे लिए कुछ हद तक क्लीनर अर्थ विज्ञान है और कम मैनुअल तारों का मतलब है, आप guice-assistedinject विस्तार classpath में, तो जब Foo बनाने (अच्छी तरह से, FooImpl, हम इंटरफेस का उपयोग करना चाहिए) की आवश्यकता होगी:

public interface FooFactory { 
    public Foo create(String bar); 
} 
फिर अपने guice मॉड्यूल में

:

@Inject 
public FooImpl(@Assisted String bar) 
{ 
    this.baz = bar; 
} 

तो फिर तुम एक FooFactory इंटरफ़ेस बनाने

install(new FactoryModuleBuilder() 
    .implement(Foo.class, FooImpl.class) 
    .build(FooFactory.class)); 

आप अधिक जटिल कारखानों वाले उदाहरणों के लिए javadoc for FactoryModuleBuilder देख सकते हैं।

+0

हाँ, यह बेकार है, यह इतना गड़बड़ है, संरचनामैप गुइस की तुलना में अधिक लचीला है। – DarthVader

+0

मैं जावा के लिए स्ट्रक्चर मैप कहां डाउनलोड कर सकता हूं? – mark

+0

यह मेरे लिए काम किया, हालांकि यह बहुत सुंदर नहीं है। –

4

मैं था पता यह पुराना धागा है लेकिन मैंने आज खुद ही इस मुद्दे को मारा। मुझे केवल 'फू' के दो या अधिकतम तीन अलग-अलग उदाहरणों की आवश्यकता है और मैं वास्तव में फैक्ट्री के सभी बोलीरप्लेट कोड नहीं लिखना चाहता था। थोड़ा गुगल करने के साथ मुझे यह Stubbisms – Tony’s Weblog मिला है, मैं इस समाधान का सुझाव दूंगा जो सही है यदि आपको पता है कि आपको वास्तव में क्या आवश्यकताएं हैं।

Guice मॉड्यूल में:

bind(Foo.class).annotatedWith(Names.named("firstFoo")).toProvider(new Provider<Foo>() { 
     @Override 
     public Foo get() { 
      return new FooImpl("topic A"); 
     } 
    }); 
    bind(Foo.class).annotatedWith(Names.named("secondFoo")).toProvider(new Provider<Foo>() { 
     @Override 
     public Foo get() { 
      return new FooImpl("topic B"); 
     } 
    }); 

या जावा 8 में:

bind(Foo.class).annotatedWith(Names.named("firstFoo")).toProvider(() -> new FooImpl("first")); 
    bind(Foo.class).annotatedWith(Names.named("secondFoo")).toProvider(() -> new FooImpl("second")); 

और अपनी सेवा के निर्माता में जहां फू उदाहरणों की जरूरत है:

@Inject 
public MyService (
    @Named("firstFoo") Foo firstFoo, 
    @Named("secondFoo") Foo secondFoo) { 
} 

और फू में मेरी मामला:

public class FooImpl implements Foo { 

    private String name; 

    public FooImpl(String name) { 
     this.name = name; 
    } 

    @Override 
    public String getName() { 
     return name; 
    } 
} 

उम्मीद है कि यह किसी की मदद करेगा।

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