प्रश्न से शब्दावली वास्तव में उदाहरण कोड के साथ मेल नहीं खाती है। Ambient Context
, संभव के रूप में आसान के रूप में किसी भी मॉड्यूल में किसी भी वर्ग से निर्भरता हड़पने के लिए निर्भरता के इंटरफ़ेस स्वीकार करने के लिए हर वर्ग प्रदूषण, लेकिन अभी भी नियंत्रण का प्रतिलोम के विचार रखने के बिना इस्तेमाल एक पैटर्न है। इस तरह की निर्भरता आम तौर पर लॉगिंग, सुरक्षा, सत्र प्रबंधन, लेनदेन, कैशिंग, ऑडिट के लिए समर्पित होती है ताकि उस आवेदन में किसी भी तरह की कटौती की चिंता हो। यह एक जोड़ने के लिए किसी भी तरह से परेशान है ILogging
, ISecurity
, ITimeProvider
कंस्ट्रक्टर्स करने के लिए और समय की सबसे नहीं सभी वर्गों के एक ही समय में सभी की जरूरत है, मैं अपनी जरूरत को समझते हैं तो।
क्या होगा यदि ISession
उदाहरण का जीवनकाल एक से भिन्न हो ILogger
? हो सकता है कि हर बार अनुरोध और ILogger पर ISession उदाहरण बनाया जाए। इसलिए ये सभी निर्भरताएँ एक वस्तु द्वारा नियंत्रित होती हैं जो कि स्वयं कंटेनर नहीं है, जीवन भर प्रबंधन और स्थानीयकरण और इस धागे में वर्णित अन्य लोगों के साथ इन सभी समस्याओं के कारण सही विकल्प नहीं दिखता है।
IAmbientContext
सवाल में हर निर्माता प्रदूषण नहीं की समस्या का समाधान नहीं है। आपको अभी भी इसका उपयोग निर्माता के हस्ताक्षर में करना है, निश्चित रूप से, इस समय केवल एक बार।
तो सबसे आसान तरीका है क्रॉस कटिंग निर्भरता से निपटने के लिए कंस्ट्रक्टर इंजेक्शन या किसी अन्य इंजेक्शन तंत्र का उपयोग नहीं करना, लेकिन एक स्थिर कॉल का उपयोग करना । हम वास्तव में इस पैटर्न को काफी बार देखते हैं, जिसे फ्रेमवर्क द्वारा ही कार्यान्वित किया जाता है। Thread.CurrentPrincipal की जाँच करें जो कि एक स्थैतिक गुण है जो IPrincipal
इंटरफ़ेस का कार्यान्वयन करता है। आप इसे पसंद करने पर कार्यान्वयन को बदल सकते हैं, इसलिए यह भी निपटान योग्य है, इस प्रकार आप इसे करने के लिए युग्मित नहीं हैं।
MyCore
अब कुछ ऐसा दिखता है
public class MyCoreClass
{
public void BusinessFeature(string data)
{
LoggerContext.Current.Log(data);
_repository.SaveProcessedData();
SessionContext.Current.SetData(data);
...etc
}
}
इस अनुच्छेद में मार्क सीमैन द्वारा इस पैटर्न और संभावित कार्यान्वयन को विस्तार से वर्णित किया गया है । ऐसे कार्यान्वयन हो सकते हैं जो आपके द्वारा उपयोग किए जाने वाले IoC कंटेनर पर निर्भर हों।
आप से बचना चाहते हैं AmbientContext.Current.Logger
, AmbientContext.Current.Session
इसी कारण के रूप में ऊपर वर्णित है।
लेकिन आपके पास इस समस्या को हल करने के लिए अन्य विकल्प हैं: सज्जाकार, गतिशील अवरोधन का उपयोग करें यदि आपके कंटेनर में यह क्षमता या एओपी है। एम्बिएंट कॉनटेक्स्ट अंतिम उपाय होना चाहिए क्योंकि इस तथ्य के कारण इसके ग्राहक इसके माध्यम से अपनी निर्भरता छिपाते हैं। मैं अभी भी परिवेश संदर्भ का उपयोग करूंगा यदि यह इंटरफ़ेस वास्तव में मेरे आवेग का उपयोग करता है जैसे कि एक स्थिर निर्भरता का उपयोग करने के लिए DateTime.Now
या ConfigurationManager.AppSettings
यह बहुत बार उठता है। लेकिन अंत में कंस्ट्रक्टर इंजेक्शन इन सर्वव्यापी निर्भरता प्राप्त करने के लिए ऐसा बुरा विचार नहीं हो सकता है।
IService
अन्य सेवाओं के साथ संचार के लिए क्या उपयोग किया जाता है?" यदिIService
अन्य सेवाओं पर अस्पष्ट निर्भरता का प्रतिनिधित्व करता है तो यह एक सेवा लोकेटर की तरह लगता है और इसका अस्तित्व नहीं होना चाहिए। आपकी कक्षा को उन इंटरफेस पर निर्भर होना चाहिए जो स्पष्ट रूप से वर्णन करते हैं कि उनके उपभोक्ता उनके साथ क्या करेंगे। किसी वर्ग को कभी भी किसी सेवा तक पहुँच प्रदान करने के लिए किसी सेवा की आवश्यकता नहीं होती है। एक वर्ग को एक निर्भरता की आवश्यकता होती है जो कुछ विशिष्ट करता है जो वर्ग को चाहिए।