2012-01-17 10 views
9

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

उत्तर

13

यदि आप कंटेनर इंजेक्ट करते हैं, तो आप निर्भरता को स्पष्ट नहीं कर रहे हैं। वास्तव में, आप उन्हें पहले से अधिक अस्पष्ट कर रहे हैं। यदि आपके पास इस तरह की कक्षा है ...

class DocumentCreator(IFileNamer fileNamer, IRepository repository) 
{ ... } 

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

, तो दूसरी ओर, यदि आप ऐसा करते ...

class DocumentCreator(IDependencyContainer container) 
{ ... } 

... आप निर्भरता छिप गए हैं। कक्षा के आंतरिक भाग की जांच किए बिना आप नहीं जानते, कि इसे आईफाइलनामर और आईरिपोजिटरी की आवश्यकता है।

न ही आप आसानी से जानते हैं कि दस्तावेज़ निर्माता का परीक्षण करने के लिए आपको कंटेनर में क्या मोक्स लगाने की आवश्यकता है। IDependencyContainer का मज़ाक उड़ाएगा आपकी मदद नहीं करेगा; आपकी कक्षा अभी भी परीक्षण में विफल रहेगी क्योंकि कंटेनर में IFileNamer और एक आईरिपोजिटरी नहीं होगी, जब तक कि आप कक्षा के आंतरिक भाग की जांच न करें, यह देखने के लिए कि उनकी आवश्यकता है।

4

मुझे लगता है कि इस दृष्टिकोण के साथ मुख्य समस्या यह है कि आप अब निर्भरताओं को स्पष्ट रूप से नहीं देखते हैं। एक और समस्या यह हो सकती है कि परीक्षण करना अधिक कठिन हो।

+0

मैं निश्चित रूप से पहले भाग से सहमत हूं, और यही कारण है कि दुर्लभ स्थितियों को छोड़कर मैं अभी भी विशिष्ट सेवाओं को इंजेक्ट करना जारी रखता हूं। लेकिन मुझे यकीन नहीं है कि इसका परीक्षण कैसे करना मुश्किल होगा? –

+1

यह कंटेनर ऑब्जेक्ट बनाने के लिए इंगित करेगा, और इसमें इंजेक्ट करने के बजाय मजाक (या मजाक नहीं) सेवाओं को इंजेक्ट करेगा, जो एक और कदम बनाता है। – greg0ire

+0

हम्म, यह निश्चित रूप से एक बड़ा नुकसान है। –

3

जो आप वर्णन करते हैं वह एक सेवा लोकेटर है। इसे आधुनिक अनुप्रयोग डिजाइन में एक विरोधी पैटर्न माना जाता है। This article क्यों बताता है।

+0

झूठा। लोगों को वास्तव में उस दोस्त के ब्लॉग से जुड़ना बंद करना होगा। यहां पैटर्न के एक अधिक कुशल मास्टर से अंतर्दृष्टि है। http://www.martinfowler.com/articles/injection.html – Colin

+1

@ कोलिन आपने कभी भी सेवा-प्रकाशक को एंटी-पैटर्न घोषित करने के लिए मार्क सीमैन के तर्क को पढ़ा है? आप केवल पूर्ण निर्भरता इंजेक्शन के कुछ फायदे प्राप्त करते हैं लेकिन कुछ लाभों को याद करते हैं (यानी निर्भरताओं की तत्काल दृश्यता)। मैं अतिरिक्त एसएल सॉफ्टवेयर डिजाइन के विभिन्न नियमों का उल्लंघन करता हूं जैसे encapsulation http://blog.ploeh.dk/2015/10/26/service-locator-violates-encapsulation/ या SOLID http://blog.ploeh.dk/2014/05/15/सेवा-लोकेटर-उल्लंघन-ठोस/ –

+0

हां, और यह बकवास है। वास्तव में, उनके तर्क के विपरीत सच है। उदाहरण के लिए, वह कहता है कि यह "खराब encapsulation" है, लेकिन encapsulation का पूरा बिंदु वर्ग के आंतरिक विवरण को छिपाना है कि कॉलर से चिंतित नहीं होना चाहिए (जैसे सत्यापन, जिसे वह अपने उदाहरण में बाहरी बनाता है)। DI में स्पष्ट अनुप्रयोग और लाभ हैं लेकिन यह "सुनहरा हथौड़ा" नहीं है; यह एक विरोधी पैटर्न है। सोचें कि क्या आपको TraceLrreneners में हर बार Trace.WriteLine() या Debug.WriteLine() कहा जाता है! मेरी इच्छा है कि लोग एक विशेषज्ञ की तरह श्रीमान सेमान का इलाज करना बंद कर देंगे; वह सिर्फ एक राय वाला ब्लॉगर है। – Colin

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

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