2015-10-12 6 views
6

मैं सरल इंजेक्टर उपयोग कर रहा हूँ एक क्षणिक सेवा पर निर्भर है इस बात का एक जीवन शैली के साथ एक सेवा पर निर्भर है scoped जिसमें क्षणिक जीवन शैली है।सरल इंजेक्टर में क्यों यह 3.0.4</p> <p>मैं एक सेवा है या एक सिंगलटन के लिए एक त्रुटि scoped सेवा

जब मैं container.Verify फोन() मैं जीवन शैली बेमेल के बारे में नैदानिक ​​त्रुटि मिलती है।

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

इसके अलावा मैंने here से इस विषय पर पहले से ही प्रलेखन पढ़ा है, और मुझे समझ में आता है कि आप एक सिंगलटन उदाहरण के लिए स्कोप्ड सेवा पर निर्भर क्यों नहीं चाहते हैं लेकिन निश्चित रूप से क्षणिक पर निर्भरता हमेशा सुरक्षित है?

उत्तर

10

हर बार जब इंजेक्शन दिए जाते हैं तो ट्रांजिस्टर ताजा नए होते हैं, इसलिए कुछ भी इसमें हस्तक्षेप नहीं कर सकता है।

यात्रियों हर बार जब आप कंटेनर से उन्हें का अनुरोध अप newed कर रहे हैं, लेकिन एक बार वे एक घटक में इंजेक्ट किया जाता है, वे जब तक कि घटक जीवन के रूप में के लिए रहेंगे। तो अगर उपभोक्ता घटक एक सिंगलटन है, इसका मतलब है कि वह अपने सभी निर्भरता के साथ खींचें होगा, उन्हें व्यावहारिक रूप से एकमात्र रूप में अच्छी तरह बना रही है।

public class SomeComponent 
{ 
    private readonly ILogger logger; 
    private readonly IService service; 

    public SomeComponent(ILogger logger, IService service) { 
     this.logger = logger; 
     this.service = service; 
    } 
} 

आप देख सकते हैं, निर्भरता घटक के निजी क्षेत्र में जमा हो जाती है, उन्हें जब तक SomeComponent के रूप में के लिए जीवित रहने के लिए कारण होगा: जब आप कैसे आप आमतौर पर निर्भरता इंजेक्शन लागू करेगा देखो यह व्यवहार स्पष्ट हो जाता है जीवन और SomeComponent समान निर्भरताओं का उपयोग जारी रखेगा।

संक्षेप में एक क्षणिक वस्तु का जीवनकाल उस सेवा द्वारा शासित होता है जिसे इसे इंजेक्शन दिया जाता है।

बिल्कुल

; एक घटक की जीवनशैली कम से कम अपने उपभोक्ता के रूप में होगी। हालांकि, निर्भरता में विभिन्न जीवन शैली वाले कई उपभोक्ता हो सकते हैं, जिससे यह देखना मुश्किल हो जाता है कि निर्भरता कब तक रहती है। जब उपभोक्ता 1 में इंजेक्शन यह अनुरोध की अवधि के लिए रहते हैं सकता है, जबकि कि निर्भरता का एक और उदाहरण, उपभोक्ता 2 में इंजेक्ट किया, जब तक कि आवेदन करता है के लिए रहना होगा।

जैसे-जैसे स्कोप्ड इंस्टेंस, क्षणिक पंजीकरण आमतौर पर थ्रेड-सुरक्षित नहीं होते हैं; अन्यथा आप उन्हें सिंगलटन के रूप में पंजीकृत कर लेते। लंबे समय तक जीवित रहने वाले को जीवित रखना, स्पष्ट रूप से स्थिर डेटा से संबंधित समवर्ती बग या बग का कारण बन सकता है। यही कारण है कि सरल इंजेक्टर डिफ़ॉल्ट रूप से इसे अस्वीकार करता है और अपवाद फेंकता है।

सरल इंजेक्टर की तुलना में ऑटोफैक अपने जीवन शैली को कैसे परिभाषित करता है, इस बारे में आप भ्रमित हो सकते हैं। Autofac में एक क्षणिक जीवन शैली नहीं है। इसकी बजाय InstancePerDependency जीवनशैली है। तकनीकी रूप से यह क्षणिक के समान है, लेकिन इरादा बहुत अलग है। InstancePerDependency के साथ आप कहते हैं: "इस घटक का उद्देश्य उपभोक्ता के रूप में तब तक जीना है, जो जीवनशैली हो सकती है"। ऐसे मामले हो सकते हैं जहां यह समझ में आता है, लेकिन ऐसा करके आप वास्तव में कमरे में हाथी को अनदेखा कर रहे हैं और मैंने पहचान की कमी को बग का एक आम स्रोत माना है।ज्यादातर मामलों में, यदि आपको किसी घटक जीवनशैली की परवाह नहीं है, तो इसका मतलब है कि इसे सिंगलटन के रूप में पंजीकृत किया जाना चाहिए - InstancePerDependency नहीं।

कारण यह है कि सरल इंजेक्टर ट्रांसपेन्ट्स को स्कॉप्ड इंस्टेंस में इंजेक्शन देने की अनुमति नहीं देता है क्योंकि स्कॉप्ड इंस्टेंस भी लंबे समय तक (एप्लिकेशन के आधार पर) रह सकते हैं और आप हमेशा यह नहीं मान सकते कि ट्रांजिस्टर सुरक्षित रूप से सुरक्षित हो सकते हैं scoped उपभोक्ताओं में इंजेक्शन।

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

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

इससे पहले कि मैं आगे जाना है और कर मेरी पूरी परियोजना स्कोप

कुछ मुझे क्या करना सलाह नहीं होता है। आप आमतौर पर देखेंगे कि आपके आवेदन में केवल कुछ 'पत्ते के घटक' को स्कॉप्ड किया गया है (जैसे DbContext)। उन scoped घटक कई अन्य घटकों पर निर्भर नहीं है। जो घटक आप स्वयं लिखते हैं उन्हें आम तौर पर स्टेटलेस होना चाहिए और किसी भी कैशिंग की आवश्यकता नहीं है। इसलिए ऑब्जेक्ट ग्राफ बनाने के मामले में सिंगलटन एक विकल्प नहीं है (अभी तक नहीं), मैं आमतौर पर ऑब्जेक्ट ग्राफ़ क्षणिक के रूप में अधिकतर बनाना चाहता हूं, और केवल उन कुछ पत्ते के घटकों को स्कॉप्ड किया जाता है। चूंकि ट्रांजिस्टर सुरक्षित रूप से स्कॉप्ड उदाहरणों पर निर्भर कर सकते हैं, इसलिए सब कुछ अपेक्षित काम करेगा।

+1

यह एक व्यापक स्पष्टीकरण है और मुझे लगता है कि मैं समझता हूं - यह सब थ्रेड सुरक्षा के बारे में है। मेरी परियोजना इस तरह से व्यवस्थित की जाती है कि एकल धागे का उपयोग कभी-कभी कई धागे द्वारा किया जाता है। स्कॉप्ड और ट्रांजिस्टर धागे के बीच साझा नहीं होते हैं। क्षणिक 1 या 2 सिंगलेट्स और स्कोप्ड के मुट्ठी भर के साथ हमारा डिफ़ॉल्ट है। जबकि त्रुटि संदेश अभी निराशाजनक है, मैं देख सकता हूं कि यह कैसे एक बुलेट चकमा देने में मेरी मदद कर सकता है अगर उसने ऐसा मामला पकड़ा जहां मेरे सिंगलटन में से एक क्षणिक पर निर्भर था। – Twisted

+0

मुझे समझ में नहीं आता है। मेरे पास थ्रेड-सेफ क्लास एक 'क्षणिक' निर्भरता के रूप में हो सकता है, जिसे सिंगलेट और अन्य क्षणिक कक्षाओं में इंजेक्शन दिया जाता है। 'लाइफस्टाइल' को थ्रेड-सुरक्षा से संबंधित होने की आवश्यकता नहीं है। (सिंगलटन <-> धागा-सुरक्षित, क्षणिक <-> गैर-थ्रेड-सुरक्षित) – Efrain

+0

@Efrain, बिंदु यह है कि क्षणिक सेवा। एक सिंगलटन में इंजेक्शन होने पर अब क्षणिक नहीं होगा। कभी-कभी यह काम कर सकता है, लेकिन यह अक्सर समस्याएं देता है और चूंकि यह बग का एक कॉमॉम स्रोत है, इसलिए सरल इंजेक्टर आपको ऐसा करने से रोकता है। यदि आपकी सेवा का उद्देश्य लंबे जीवन जीने का है: इसे सिंगलटन बनाएं। – Steven

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