12

यह क्योंकि मेरे कोड सब कुछ काम कर रहा है में एक बेवकूफ सवाल लग सकता है, लेकिन मैं अपने एकता कंटेनर _ambientContainer के साथ एक सिंगलटन इस तरह से पंजीकृत कर लिया है:यूनिटीकॉन्टेनर। रिसोलव या सर्विस लोकेटर। गेट इंस्टेंस?

_ambientContainer.RegisterType<Application.StateContext>(new ContainerControlledLifetimeManager()); 

क्रम में, मैं का उपयोग अपने स्थानीय क्षेत्र का उपयोग करने से बचने के लिए :

get { 
    return ServiceLocator.Current.GetInstance<Application.StateContext>(); 
} 

मेरी ऑब्जेक्ट का उदाहरण प्राप्त करने के लिए मेरी संपत्ति के अंदर। इस तरह से मैं हमेशा एक ही उदाहरण प्राप्त करता हूं (Application.StateContext अभी भी एक सिंगलटन है) या GetInstance नया बनाता है?

क्या स्थानीय _ambientContainer फ़ील्ड का उपयोग करना बेहतर है?

get { 
    return _ambientContainer.Resolve<Application.StateContext>(); 
} 

धन्यवाद।

उत्तर

5

मैं यह सोचते हैं रहा है कि ServiceLocator प्रकार CommonServiceLocator परियोजना से है, और आप एकता एडाप्टर, जिसमें मामले GetInstance invokes container.Resolve का उपयोग कर रहे हैं, इसलिए दोनों लाइनों के बराबर हैं।

आप यहाँ स्रोत देख सकते हैं - http://commonservicelocator.codeplex.com/wikipage?title=Unity%20Adapter&referringTitle=Home

7

अधिमानतः तुम दोनों तरीकों (ab) अपने कंटेनर का उपयोग कर से बचना चाहिए।

आधुनिक अनुप्रयोग आर्किटेक्चर में ServiceLocator is considered an anti-pattern

+1

क्या आपके पास एक विकल्प का सुझाव है? (प्रश्न में उदाहरण कोड के लिए विशिष्ट?) – Adam

+0

@Adam कोड के लिए एक विकल्प? गेटटर? या 'Application.StateContext' का पंजीकरण? लेखक ने यह नहीं बताया कि वह किस प्रकार का एप्लिकेशन उपयोग करता है (asp.net/mcv, winforms, wpf, console, wcf ...) इसलिए मैं आपको यह नहीं बता सकता कि आपको पंजीकरण कोड रखना था। प्रत्येक प्रकार के ऐप में एक अलग [संरचना रूट] होता है (http://blog.ploeh.dk/2011/07/28/CompositionRoot.aspx)। सेवा लोकेटर को कॉल करने के लिए: उन राज्यों के 'स्टेटकॉन्टेक्स्ट' को एक सीटीओ पैरामीटर बनाएं, जिसकी आवश्यकता है। इससे निर्भरता स्पष्ट और अदला-बदली हो जाती है (उदाहरण के लिए परीक्षण के लिए)। –

+1

यदि आप इसे गलत तरीके से उपयोग करते हैं तो कोई भी पैटर्न एक विरोधी पैटर्न है। सभी डी पुस्तकालय कवर के तहत सेवा स्थान का उपयोग करते हैं अन्यथा वे काम नहीं करते हैं। इंटरनेट पर जो कुछ भी आप पढ़ते हैं उस पर विश्वास न करें! – JBeckton

15

उपभोक्ता वर्गों के लिए कंटेनर के उदाहरण के आसपास पासिंग, एक अच्छा विचार है कि आम तौर पर नहीं है, क्योंकि आप अब अपने आवेदन में एक एकल जगह है जहाँ घटकों और सेवाओं पंजीकृत किया जा रहा है (Composition Root रूप में जाना जाता है) की गारंटी कर रहे हैं ।

वर्ग उनके सार्वजनिक एपीआई में उनकी निर्भरता लिखा होना चाहिए, specifying them as constructor arguments, जो कंटेनर स्वचालित रूप से जब भी यह एक विशेष प्रकार का (एक प्रक्रिया रूप में जाना जाता Autowiring) को हल करने के लिए कहा गया है के लिए एक उदाहरण प्रदान करेगा द्वारा आदर्श।

Dependency Injection आमतौर पर the preferred choice है लेकिन यह हमेशा लागू नहीं होता है। उन मामलों में Service Locator का उपयोग करके, जैसा कि आप अपने उदाहरण में कर रहे हैं, decouple a class from its dependencies पर अगले सर्वोत्तम समाधान है।

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

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