2013-05-01 7 views
11

गहराई से इंजेक्शन की सहायता की है, मैं प्रसंस्करण तत्वों की एक श्रृंखला आयोजित करना चाहता हूं और उन्हें गुइस के माध्यम से एक साथ तार करना चाहता हूं। के निम्न पथ मान लेते हैं:गुइस ने निर्भरता पदानुक्रम

  • interface Aclass AImpl द्वारा कार्यान्वित कुछ इनपुट
  • interface Bclass BImpl जरूरतों A
  • interface Cclass CImpl जरूरतों B
  • interface Dclass DImpl जरूरतों C
द्वारा कार्यान्वित द्वारा कार्यान्वित द्वारा कार्यान्वित की जरूरत है

ए की निर्भरता केवल रनटाइम पर हल की जा सकती है, कॉन्फ़िगरेशन समय पर नहीं।

public interface DFactory { 
    public D createD(String inputForA); 
} 
:

public interface AFactory { 
    public A createA(String input); 
} 

लेकिन क्या मैं वास्तव में चाहते हैं कुछ इस तरह है: हमेशा की तरह दृष्टिकोण सिर्फ इस तरह, इस मामले में असिस्टेड इंजेक्शन का उपयोग करने के एक कारखाने, कि पैरामीटर के रूप में लापता उदाहरणों लेता है बनाने के लिए किया जाएगा

मैं पूरे पदानुक्रम के माध्यम से AImpl-विशिष्ट निर्भरता मैन्युअल रूप से पास नहीं करना चाहता हूं। क्या यह गुइस के साथ इसे हासिल करना संभव है? यदि नहीं, इंजेक्शन के लाभों को बनाए रखने के दौरान, इस समस्या को सुस्त तरीके से रोकने का सबसे अच्छा तरीका क्या है?

उत्तर

7

धोखाधड़ी का रास्ता: स्थिर स्थिर या सिंगलटन ThreadLocal में input चिपकाएं। अपनी पाइपलाइन शुरू होने से पहले इसे सेट करें और इसे समाप्त होने के बाद साफ़ करें। DI के माध्यम से सबकुछ बांधें।

फैंसी तरीका:A में, एक @PipelineInput String inputString का उल्लेख है, लेकिन अपने मुख्य इंजेक्टर में यह बाँध नहीं है। अन्यथा, अन्य पाइपलाइन से संबंधित वर्गों में @PipelineInput का जिक्र करते हुए सामान्य रूप से निर्भरताएं बाध्य करें। जब आपको D की आवश्यकता होती है, तो इसे DFactory के कार्यान्वयन से प्राप्त करें, जिसे मैं PipelineRunner पर कॉल कर रहा हूं।

public class PipelineRunner { 
    @Inject Injector injector; // rarely a good idea, but necessary here 

    public D createD(final String inputForA) { 
    Module module = new AbstractModule() { 
     @Override public void configure() { 
     bindConstant(inputForA).annotatedWith(PipelineInput.class); 
     } 
    }; 
    return injector.createChildInjector(new PipelineModule(), module) 
     .getInstance(D.class); 
    } 
} 

स्वाभाविक रूप से, बंधन प्रयासों के लिए A, B, C, और D एक @PipelineInput String की कमी --you'll आप के रूप में एक CreationException मिलता है जब आप उन असंतुष्ट निर्भरता के साथ इंजेक्टर बनाने के लिए, के लिए PipelineRunner के बाहर असफल हो जायेगी खोजा गया - लेकिन उन पाइपलाइन-आधारित निर्भरताओं को एक मॉड्यूल में अलग करना आसान होना चाहिए जिसे आप बच्चे इंजेक्टर में स्थापित करते हैं।

यह भी hacky लगता है, याद रखें कि PrivateModules भी कर रहे हैं "implemented using parent injectors", और कहा कि निर्भरता इंजेक्शन के पूरे मुद्दे एक decoupled तरह से inputForA पूरी वस्तु ग्राफ के लिए उपलब्ध की तरह एक निर्भरता बनाने के लिए है।

+0

मुझे अपनी मंजूरी याद करनी है, इस बारे में बताएं: "ए, बी के लिए इंजेक्शन प्रयास , सी, और डी @PipelineInput स्ट्रिंग की कमी के लिए पाइपलाइनरुनर के बाहर असफल हो जाएंगे "यह काम नहीं करता है, क्योंकि गुइस कॉन्फ़िगरेशन समय पर इंजेक्टरों को सत्यापित करता है और जैसे ही यह एक असंतुष्ट बाध्यकारी का पता लगाता है, असल में आप लगभग एक नहीं बना सकते पूर्ण इंजेक्टर, जो उसके बच्चे द्वारा पूरा किया जाएगा। निजी मॉड्यूल एक विशेष बांधने की मशीन का उपयोग करके इसे दूर करते हैं। – orsg

+0

मेरी गलती; आपको निरंतर के आस-पास ए, बी, सी, और डी को बांधना होगा। हालांकि, ठीक करने के लिए मुश्किल है। उत्तर अपडेट किया गया। –

+1

ठीक है, इसलिए मुझे बच्चे इंजेक्टर के अंदर विशेष रूप से पाइपलाइन से संबंधित सब कुछ बांधना है और माता-पिता इंजेक्टर केवल कारखाने ("पाइपलाइनरुनर") के बारे में जानता है। – orsg

1

मुझे तीन विकल्प दिखाई देते हैं। वे के लिए input को कितनी बार बदलते हैं इस पर निर्भर करते हैं।

1) अपने मॉड्यूल में निरंतर के रूप में input बांधें। यह केवल तभी काम करता है, यदि आप Injector बनाने से पहले उस मान को जानते हैं और कभी भी मूल्य बदलना नहीं चाहते हैं। देखें bindConstant

2) एक निजी सबमिशन का उपयोग करें जो A या उस मॉड्यूल के अंदर input के लिए मान को बांधता है। असल में आपके पास अलग-अलग मान के साथ दो या तीन इंस्टेंस ग्राफ़ हो सकते हैं। newPrivateBinder देखें।

3) का प्रयोग करें एक Scope आला RequestScope, SessionScope ... इस तरह से आप इनपुट अक्सर बदल सकते हैं लेकिन आप दर्ज/कुछ बिंदु पर गुंजाइश छोड़ परिभाषित किया जाना चाहिए। उदाहरण के लिए Custom Scopes देखें।

+0

1) बहुत देर हो चुकी है और 2) केवल 1 का एक विशेष मामला है)। मैंने स्कॉप्स के बारे में भी सोचा, लेकिन इतनी छोटी समस्या के लिए यह इतना बॉयलरप्लेट है कि मैं ग्यारहता के लिए डीआई को पूरी तरह छोड़ दूंगा: - – orsg

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