Guice

2010-09-25 12 views
12

निम्नलिखित कोड में एक सामान्य कारखाने इंजेक्शन एक कारखाने है कि एक Bar<T> का उत्पादन एक Foo<T> दिया का एक उदाहरण है। कारखाने परवाह नहीं है कि T है: किसी भी प्रकार के T के लिए, यह Foo<T> से Bar<T> बना सकता है।Guice

import com.google.inject.*; 
import com.google.inject.assistedinject.*; 

class Foo<T> { 
    public void flip(T x) { System.out.println("flip: " + x); } 
} 

interface Bar<T> { 
    void flipflop(T x); 
} 

class BarImpl<T> implements Bar<T> { 
    Foo<T> foo; 

    @Inject 
    BarImpl(Foo<T> foo) { this.foo = foo; } 

    public void flipflop(T x) { foo.flip(x); System.out.println("flop: " + x); } 
} 

interface BarFactory { 
    <T> Bar<T> create(Foo<T> f); 
} 

class Module extends AbstractModule { 
    public void configure() { 
    bind(BarFactory.class) 
     .toProvider( 
      FactoryProvider.newFactory(BarFactory.class, BarImpl.class) 
        ); 
    } 
} 

public class GenericInject { 
    public static void main(String[] args) { 
    Injector injector = Guice.createInjector(new Module()); 

    Foo<Integer> foo = new Foo<Integer>(); 
    Bar<Integer> bar = injector.getInstance(BarFactory.class).create(foo); 
    bar.flipflop(0); 
    } 
} 

जब मैं कोड चलाने के लिए, मैं Guice से निम्न त्रुटियों मिलती है:

1) No implementation for BarFactory was bound. 
    at Module.configure(GenericInject.java:38) 

2) Bar<T> cannot be used as a key; It is not fully specified. 

केवल संदर्भ मैं Guice दस्तावेज में जेनरिक के लिए मिल सकता है एक TypeLiteral उपयोग करने के लिए कहते हैं। लेकिन मेरे पास शाब्दिक प्रकार नहीं है, मेरे पास एक सामान्य प्लेसहोल्डर है जो कारखाने के लिए प्रासंगिक नहीं है। कोई सुझाव?

उत्तर

-1

यदि आप वसंत के समान तारों की एक प्रणाली के रूप में गुइस के बारे में सोचते हैं, तो यह वास्तव में एक सामान्य उदाहरण तार करने के लिए समझ में नहीं आता है। आप कुंजी के लिए विशिष्ट उदाहरण तारों को तारित कर रहे हैं, ताकि जब एक और तत्काल वर्ग @ इंजेक्ट बारफैक्टरी के साथ कुछ चिह्नित करता है तो आपको विशिष्ट निर्मित उदाहरण मिलता है।

चूंकि आपका कार्यान्वयन सामान्य है, इसलिए आपने एक विशिष्ट उदाहरण इंजेक्ट करने के लिए पर्याप्त जानकारी प्रदान नहीं की है। हालांकि मैंने फैक्ट्रीप्रोवाइडर का उपयोग नहीं किया है, मेरी धारणा यह है कि आपको बारफैक्टरी को पूरी तरह पैरामीटरयुक्त उदाहरण में बाध्य करने की आवश्यकता होगी, उदा। Bar12mpl के बजाय BarImpl<Concrete>)

संयोग से जब आप बारफैक्टरी.क्लास को बाध्य कर रहे हैं, तो आप कई उदाहरणों को बांधना चाहते हैं, तो आपको किसी भी तरह से नाम से कुछ भी बदलना होगा, जैसे कुछ (वाक्यविन्यास की जांच नहीं की गई है, लेकिन)

bind(BarFactory.class).annotatedWith(Names.named("name1")) 
     .toProvider( 

or by generics, bind(BarFactory<Concrete>).toProvider... 
+1

बारफैक्टरी सामान्य नहीं है, इसलिए इसे जिस तरह से मैंने तार दिया है उसे तार करने के लिए यह सही समझ में आता है। बार के एक पैरामिट्रीकृत उदाहरण अनुबंध से मेल खाएंगे नहीं: एक फू लेने के लिए करने के लिए की जरूरत है बना सकते हैं और एक बार वापसी किसी भी टी –

4

एक विकल्प सिर्फ हाथ से BarFactory बॉयलरप्लेट लिखना है:

class BarImplFactory implements BarFactory { 
    public <T> Bar<T> create(Foo<T> f) { 
    return new BarImpl(f); 
    } 
} 

बाध्यकारी हो जाता है

bind(BarFactory.class).to(BarImplFactory.class); 
+0

विल Guice के लिए इंजेक्षन 'भले ही उसके निर्माता के बिना स्पष्ट रूप से कहा जाता है की जा रही है BarImpl' के अन्य निर्माता मानकों Guice? –

+1

नहीं, मुझे ऐसा नहीं लगता है। आपको अभी भी अपने स्वयं के फ़ूज़ प्रदान करने की आवश्यकता होगी। –

+2

@ जेफ एक्सलरोड, आप BarImpl के अन्य कन्स्ट्रक्टर पैराम को इंजेक्ट कर सकते हैं, पहले बारइम्पल फैक्ट्री के कन्स्ट्रक्टर को इंजेक्शन करके और फिर उन मानों की प्रतिलिपि बना सकते हैं। – Shuo

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