2010-10-21 17 views
12

ऐसा कुछ है जो मुझे सिर्फ गुइस के बारे में नहीं मिलता है: मैंने जो अभी तक पढ़ा है, उसके अनुसार, मुझे केवल अपने बूटस्ट्रैपिंग क्लास में इंजेक्टर का उपयोग करना है (एक स्टैंडअलोन एप्लिकेशन में यह आमतौर पर मुख्य() में होगा विधि) नीचे दिए गए उदाहरण की तरह (guice प्रलेखन से लिया गया):guice का उपयोग करते समय सभी जगह injector.createInstance() होने से कैसे बचें?

public static void main(String[] args) { 
    /* 
    * Guice.createInjector() takes your Modules, and returns a new Injector 
    * instance. Most applications will call this method exactly once, in their 
    * main() method. 
    */ 
    Injector injector = Guice.createInjector(new BillingModule()); 

    /* 
    * Now that we've got the injector, we can build objects. 
    */ 
    RealBillingService billingService = injector.getInstance(RealBillingService.class); 
    ... 
    } 

लेकिन क्या होगा अगर नहीं सभी वस्तुओं मैंने कभी जरूरत स्टार्टअप के दौरान बनाया जा सकता है? हो सकता है कि जब एप्लिकेशन चल रहा हो तो मैं कुछ उपयोगकर्ता इंटरैक्शन का जवाब देना चाहता हूं? क्या मुझे अपने इंजेक्टर को कहीं और नहीं रखना है (उदा। एक स्थिर चर के रूप में) और फिर इंजेक्टर.getInstance (SomeInterface.class) को कॉल करें जब मुझे कोई नई वस्तु बनाने की आवश्यकता हो?

बेशक, जगह पर इंजेक्टर.getInstance() पर कॉल फैलाने के लिए वांछनीय नहीं लगता है।

मुझे यहां क्या गलत हो रहा है?

उत्तर

12

हां, मूल रूप से केवल रूट-ऑब्जेक्ट के लिए उदाहरण प्राप्त करने के लिए इंजेक्टर का उपयोग करना चाहिए। शेष आवेदन गुइस-कंटेनर को छूना नहीं चाहिए। जैसा कि आपने देखा है, आपको आवश्यकता होने पर भी कुछ वस्तुओं को बनाने की आवश्यकता है। ऐसा करने के लिए अलग-अलग दृष्टिकोण हैं, प्रत्येक अलग-अलग आवश्यकताओं के लिए उपयुक्त है।

एक प्रदाता Provider सम्मिलित करें Guice से एक इंटरफेस है। यह आपको किसी ऑब्जेक्ट के नए उदाहरण का अनुरोध करने की अनुमति देता है। वह वस्तु गुइस का उपयोग करके बनाई जाएगी। उदाहरण के लिए।

class MyService{ 
    private Provider<Transaction> transactionProvider; 
    public MainGui(Provider<Transaction> transactionProvider){ 
     this.transactionProvider = transactionProvider; 
    } 

    public void actionStarted(){ 
     Transaction transaction = transactionProvider.get(); 
    } 

बिल्ड एक फैक्टरी अक्सर आप कारखाने के कुछ प्रकार की जरूरत है। यह कारखाना कुछ इंजेक्शन सेवाओं और कुछ पैरामीटर का उपयोग करता है और आपके लिए एक नई वस्तु बनाता है। फिर आप इस फैक्ट्री का इस्तेमाल नए उदाहरणों के लिए करते हैं। फिर आप उस कारखाने को इंजेक्ट करते हैं और इसका इस्तेमाल करते हैं। इसके लिए AssistedInject-extension

मुझे लगता है कि इन दो संभावनाओं के साथ आपको शायद ही कभी गिइस-इंजेक्टर का उपयोग करने की आवश्यकता है। हालांकि कभी-कभी इंजेक्टर का उपयोग करने के लिए अभी भी उपयुक्त है। फिर आप एक घटक को इंजेक्टर इंजेक्ट कर सकते हैं।

3

उत्तर पर विस्तार करने के लिए Gamlor पोस्ट किया गया है, तो आप जिस ऑब्जेक्ट प्रकार का उपयोग कर रहे हैं उसके बीच भी अंतर करने की आवश्यकता है।

सेवाओं के लिए, इंजेक्शन सही समाधान है, हालांकि, हमेशा डेटा ऑब्जेक्ट्स (जो आमतौर पर आपके ऑब्जेक्ट ग्राफ़ में पत्ते होते हैं) इंजेक्शन करने की कोशिश नहीं करते हैं। ऐसी परिस्थितियां हो सकती हैं जहां यह सही समाधान है, लेकिन Provider<List> इंजेक्शन करना शायद एक अच्छा विचार नहीं है। मेरा एक सहयोगी समाप्त हो गया, उसने थोड़ी देर बाद कोड आधार को बहुत भ्रमित कर दिया। हमने अभी इसे साफ कर लिया है और गुइस मॉड्यूल अब और अधिक विशिष्ट हैं।

+0

हां, मैं पूरी तरह से इसके साथ सहमत हूं। – Gamlor

0

सार में, मुझे लगता है कि सामान्य विचार

BillingService billingService = injector.getInstance(BillingService.class); 
billingService.respondToUserEvent(event); 

मुझे लगता है कि अगर उपयोगकर्ता घटनाओं का जवाब है, तो अच्छी तरह से आपके आवेदन की क्षमताओं का हिस्सा है, ... कि एक छोटे से सार हो सकता है , लेकिन मूल विचार यह है कि आप अपने उच्च स्तरीय आवेदन वर्ग के गुइस से प्राप्त करते हैं। आपके प्रश्न से निर्णय लेते हुए, मुझे लगता है कि शायद बिलिंग सेवा आपकी शीर्ष-स्तरीय कक्षा नहीं है?

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

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