2015-01-28 6 views
6

मैं काफी बड़ी परियोजना पर काम कर रहा हूं जिसमें बहुत सारे इंजेक्शन हैं। हम वर्तमान में एक कक्षा का उपयोग कर रहे हैं जो प्रत्येक इंजेक्शन के लिए Provider लागू करता है, जिसके लिए एक की आवश्यकता होती है, और उनमें अधिकतर एक पंक्ति get विधियां होती हैं।Guice @ प्रावधान विधियों बनाम प्रदाता वर्ग

हर बार जब मुझे एक नया प्रदाता चाहिए तो एक नई कक्षा बनाने के लिए परेशान होना शुरू हो रहा है। क्या में @Provides विधियों पर प्रदाता कक्षाओं का उपयोग करने के लिए कोई लाभ है या इसके विपरीत?

उत्तर

16

जहां तक ​​मुझे पता है, वे सबसे साधारण मामलों के बराबर हैं।

/** 
* Class-style provider. 
* In module: bind(Foo.class).annotatedWith(Quux.class).toProvider(MyProvider.class); 
*/ 
class MyProvider implements Provider<Foo> { 
    @Inject Dep dep; // All sorts of injection work, including constructor injection. 

    @Override public Foo get() { 
    return dep.provisionFoo("bar", "baz"); 
    } 
} 

/** 
* Method-style provider. configure() can be empty, but doesn't have to be. 
*/ 
class MyModule extends AbstractModule { 
    /** Name doesn't matter. Dep is injected automatically. */ 
    @Provides @Quux public Foo createFoo(Dep dep) { 
    return dep.provisionFoo("bar", "baz"); 
    } 

    @Override public void configure() { /* nothing needed in here */ } 
} 

या तो शैली में, Guice आप Foo और Provider<Foo> इंजेक्षन, भले ही कुंजी कक्षा या उदाहरण के लिए बाध्य है की सुविधा देता है। अगर कोई उदाहरण मौजूद नहीं है तो गुइस स्वचालित रूप से get पर कॉल करता है और एक अंतर्निहित Provider<Foo> बनाता है। बाइंडिंग एनोटेशन दोनों शैलियों में काम करते हैं।

@ प्रावॉइड का मुख्य लाभ कॉम्पैक्टनेस है, खासकर अज्ञात आंतरिक प्रदाता कार्यान्वयन की तुलना में। हालांकि, ध्यान रखें कि कुछ ऐसे मामले हो सकता है जहाँ आप प्रदाता वर्गों के पक्ष में करना चाहते हैं: ऐसे मामलों को

  • आप संभवतः निर्माता मानकों के साथ अपने स्वयं के लंबे समय तक रहा प्रदाता उदाहरण बना सकते हैं, और बाँध कुंजी वर्ग शाब्दिक के बजाय।

    bind(Foo.class).toProvider(new FooProvisioner("bar", "baz")); 
    
  • आप एक रूपरेखा JSR 330 (javax.inject) के साथ संगत का उपयोग कर रहे हैं, तो आप आसानी से javax.inject.Provider वर्ग या उदाहरणों के लिए बाध्य कर सकते हैं। com.google.inject.Provider उस इंटरफ़ेस को बढ़ाता है।

    bind(Foo.class).toProvider(SomeProviderThatDoesntKnowAboutGuice.class); 
    
  • आपका प्रदाता अपनी कक्षा में कारक बनाने के लिए पर्याप्त जटिल हो सकता है। इस पर निर्भर करते हुए कि आपने अपने परीक्षणों को कैसे संरचित किया है, इस प्रकार आपके प्रदाता को इस तरह से जांचना आसान हो सकता है।

  • प्रदाता अमूर्त कक्षाएं बढ़ा सकते हैं। @Provides विधियों के साथ ऐसा करना आसान या सहज नहीं हो सकता है।

  • आप एक ही प्रदाता को सीधे कई चाबियाँ बांध सकते हैं। प्रत्येक @ प्रावॉइड विधि वास्तव में एक बाध्यकारी उत्पन्न करती है, हालांकि आप अन्य कुंजियों को कुंजी (@Quux Foo यहां) से जोड़ सकते हैं और गुइस को दूसरा लुकअप करने दें।

  • प्रदाता आसानी से सजाने या लपेटने में आसान होते हैं, अगर आप (उदाहरण के लिए) कैश या गुइस स्कोप्स या बाइंडिंग का उपयोग किए बिना उदाहरणों को याद करते हैं।

    bind(Foo.class).toProvider(new Cache(new FooProvisioner("bar", "baz"))); 
    

महत्वपूर्ण: हालांकि इस वर्ग जो Guice नहीं बना सकते, मन में भालू है कि Guice स्वचालित रूप से बना सकते हैं और किसी भी टी के लिए एक Provider<T> इंजेक्षन कर सकते हैं के लिए एक अच्छी रणनीति है कि आप bind किसी भी तरह से, कक्षा के नाम, कुंजी या उदाहरण सहित। जब तक कि आपके स्वयं के शामिल होने का वास्तविक तर्क न हो, तब तक एक स्पष्ट प्रदाता बनाने की आवश्यकता नहीं है।

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