2016-09-05 18 views
19

का उपयोग कर विधि इंजेक्शन मैंने डैगर 2 का उपयोग करके विधि इंजेक्शन पर एक अच्छा स्पष्टीकरण/उदाहरण नहीं पाया है। क्या कोई मुझे समझने में मदद कर सकता है?डैगर 2

उदाहरण:

@Inject 
public Dinner makeDinner(Pasta pasta, Sauce sauce) { 
    mPan.add(pasta); 
    mPan.add(sauce); 
    return mPan.cookDinner(); 
} 

तो अगर मैं @Inject के साथ मेरी विधि व्याख्या करते हैं, कर रहा हूँ मुझे लगता है कि करने के लिए विधि हस्ताक्षर में तर्क वस्तु ग्राफ से परिभाषित वस्तुओं के साथ इंजेक्शन दिया जाएगा सही हूँ? मैं अपने कोड में इस विधि का उपयोग कैसे कर सकता हूं? यह अभी भी मुझे सभी तर्कों की आपूर्ति करने की उम्मीद करेगा, जब मैं विधि कॉल करता हूं, इस उद्देश्य को किस तरह से हराया जाता है।

अद्यतन:

मैं क्या समझ अगर मैं DinnerComponent.dinner() फोन डिनर वस्तु उपलब्ध हो जाएगा, यह मानते हुए मेरी DinnerComponent इस तरह की स्थापना की है से

तो:

@Component(modules = DinnerModule.class) 
public interface DinnerComponent { 
    Dinner dinner(); 
} 

और मेरे DinnerModule की स्थापना की है इस तरह:

@Module 
public class DinnerModule { 
    public DinnerModule() {} 

    @Provides 
    Pasta providePasta() { return new Pasta(); } 

    @Provides 
    Sauce provideSauce() { return new Sauce(); } 
} 

क्या होता है यदि मैं अपना डिनर तला हुआ चाहता हूं?

@Inject 
public Dinner makeDinner(Pasta pasta, Sauce sauce) { 
    mPan.add(pasta); 
    mPan.add(sauce); 
    return mPan.fryDinner(); 
} 

मैं घटक है जो रात के खाने के है जो भीतर कैसे निर्दिष्ट कर सकते हैं: तो चलो इस पद्धति को लागू करते हैं?

+0

मुझे यकीन नहीं है कि आपको यह उदाहरण कहां मिला, लेकिन मुझे लगता है कि आपको लगता है कि आप सहायता इंजेक्शन के बारे में पढ़ना चाहेंगे। –

+0

आप @ नामांकित एनोटेशन का उपयोग कर सकते थे। –

उत्तर

22

विधि इंजेक्शन कि जिस तरह से से अलग है के बारे में एक मौलिक अंतर आप यह है कि method injection is just another way for Dagger to send in dependencies जब निर्माण या एक डि तैयार वस्तु, जिसका अर्थ है कि @ इंजेक्षन-एनोटेट तरीकों के नाम से जाना के लिए होती हैं इंजेक्शन लगाने के ज़रिये जुड़े हुए हैं एक बार निर्माण पर एक बार डैगर द्वारा और अपने कोड के भीतर से नहीं। इससे यह बहुत ही असंभव हो जाता है कि आप @Inject -annotate makeDinner, fryDinner, या किसी भी अन्य विधि का अर्थपूर्ण साइड इफेक्ट्स या वापसी मूल्य हैं। इसके बजाय, कन्स्ट्रक्टर-शैली इंजेक्शन के लिए एक वास्तविक तथ्य के रूप में विधि इंजेक्शन का इलाज करें।

public class Chef { 
    private Provider<Pasta> mPastaProvider; 
    private Sauce mSauce; 

    @Inject 
    public void registerIngredients( // can be named anything 
     Provider<Pasta> pastaProvider, 
     Sauce sauce) {     // T and Provider<T> both work, of course 
    mPastaProvider = pastaProvider; 
    mSauce = sauce; 
    } 

    /* [email protected] */ public Dinner cookDinner() { 
    mPan.add(mPastaProvider.get()); 
    mPan.add(mSauce); 
    return mPan.cookDinner(); 
    } 

    /* [email protected] */ public Dinner fryDinner() { 
    mPan.add(mPastaProvider.get()); 
    mPan.add(mSauce); 
    return mPan.fryDinner(); 
    } 
} 

इस मामले में, आप एक बावर्ची पर इंजेक्शन अनुरोध करते हैं, डैगर @ इंजेक्षन-एनोटेट विधि देख सकते हैं और यह कॉल करेंगे। जब तक आपके पास @ इंजेक्शन-एनोटेटेड कन्स्ट्रक्टर या @ प्रवाइड विधि नहीं है, तो आप सीधे अपने घटक से शेफ प्राप्त नहीं कर पाएंगे, लेकिन घटक पर void विधि बना सकता है जो एक निर्मित Chef उदाहरण प्राप्त करता है और कौन सा उपयोग करता है क्षेत्र और विधि इंजेक्शन प्रदान करने के लिए कि सामग्री (या घटक प्रदाता) के साथ महाराज की आवश्यकता हो सकती है। (विवरण के लिए @Component और MembersInjector दस्तावेज़ देखें।)

ध्यान दें कि किसी भी मामले में Dinner ऑब्जेक्ट ग्राफ़ पर उपलब्ध नहीं है!एक कंस्ट्रक्टर को @ इंजेक्ट जोड़ना डैगर को बताता है कि यह ऑब्जेक्ट ग्राफ़ पर ऑब्जेक्ट को उपलब्ध कराने के लिए उस कन्स्ट्रक्टर का उपयोग कर सकता है, लेकिन एक विधि या फ़ील्ड में इंजेक्ट जोड़ना केवल डैगर को बताता है कि इंजेक्शन प्रक्रिया के हिस्से के रूप में इसे उस क्षेत्र या कॉल को पॉप्युलेट करना चाहिए दी गई निर्भरताओं के साथ वह विधि। यदि आप ऑब्जेक्ट ग्राफ़ पर एक डिनर उपलब्ध करना चाहते हैं, तो आपको डिनर कन्स्ट्रक्टर को इंजेक्ट-एनोटेट करना होगा, या घटक में फ़ीड करने वाले मॉड्यूल पर @ प्रावॉइड या @ बाइंड्स विधि डालना होगा।

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

+2

इस जवाब को कई बार पढ़ने के बाद, और अपने लिए यह कोशिश कर रहा है, मुझे लगता है कि मैं अंततः विधि इंजेक्शन पर गति करने के लिए तैयार हूं। धन्यवाद! – Vas

5

@Inject के साथ एक विधि को एनोटेट करने से ऑब्जेक्ट के निर्माण के ठीक बाद इस विधि को निष्पादित करने के लिए डैगर निर्देश दिए जाते हैं - कन्स्ट्रक्टर कॉल के ठीक बाद। यह तब उपयोगी होता है जब आपको किसी चीज़ के लिए पूरी तरह से निर्मित वस्तु की आवश्यकता होती है। this article में विधि इंजेक्शन का एक उदाहरण है।

आप यह कहकर सही कह रहे हैं कि इस विधि के पैरामीटर डैगर द्वारा प्रदान किए जाएंगे, यही कारण है कि आपको इस विधि को स्वयं से कॉल नहीं करना है।

+0

ठीक है, तो मुझे अपना प्रश्न तब अपडेट करें। – Vas

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