दिलचस्प पोस्ट
mysqli bind_param () एक संदर्भ होने की उम्मीद, मूल्य दिया सी जोरदार टाइप किया गया है? मैं अपने डिवाइज़ को क्षैतिज रूप से कैसे संरेखित कर सकता हूं? स्ट्रिंग से एकल वर्ण कैसे निकालें UISegmentedControl का फ़ॉन्ट आकार बदलें जावास्क्रिप्ट में मल्टी-आयामी एसोसिएटिव एरेज़ दो डेटाबेस के बीच विदेशी कुंजी संबंध जोड़ें एंड्रॉइड में पुनरावृत्त गतिशील जेएसएन स्ट्रिंग के माध्यम से लूप करने में असमर्थ एक बैच फ़ाइल के अंदर प्रशासक का उपयोग करने का अनुरोध कैसे करें Google Apps स्क्रिप्ट में किसी अन्य HTML पृष्ठ से लिंक करना विंडोज सेवा के रूप में नेट कंसोल एप्लीकेशन jQuery AJAX वर्ण एन्कोडिंग कैसे प्रोग्राम की मात्रा को सिस्टम मात्रा निर्धारित करें? awk / sed: एक रिकर्सिव कैसे खोज / एक स्ट्रिंग की जगह है? क्यों फ़ायरफ़ॉक्स के लिए ग़रक़ीडर की जरूरत है?

निर्भरता इंजेक्शन – एक क्लास विधियों में से कई में आवश्यक नए उदाहरण

मेरे पास कुछ कोड है जो ऐसा कुछ दिखता है:

public MyService(IDependency dependency) { _dependency = dependency; } public Message Method1() { _dependency.DoSomething(); } public Message Method2() { _dependency.DoSomething(); } public Message Method2() { _dependency.DoSomething(); } 

अब मुझे एहसास हुआ है कि क्योंकि निर्भरता वस्तु में आंतरिक स्थिति की जानकारी है मुझे प्रत्येक पद्धति कॉल में एक नया इंस्टेंस तैयार करना होगा

तो यह करने का सबसे अच्छा तरीका क्या है और अभी भी एक ठोस उदाहरण का नयाकरण नहीं किया गया है?

क्या आप आईओसी कंटेनर का उपयोग करते हैं और हर एक तरीके में कंटेनर को कॉल करते हैं? या वहाँ एक सख्त तरीका है जहां आप केवल एक कंटेनर को कॉल कर सकते हैं?

अगर मैं एक आईओसी कंटेनर का उपयोग नहीं कर रहा था तो क्या होगा – क्या प्रत्येक पद्धति में एक ठोस उदाहरण को न लेने का कोई तरीका होगा?

वेब के समाधान से एकत्रित समाधान "निर्भरता इंजेक्शन – एक क्लास विधियों में से कई में आवश्यक नए उदाहरण"

यहां से अधिकांश उत्तर अब तक सुझाव देते हैं कि आप इस मुद्दे को सुलझाने के लिए किसी प्रकार की सार फैक्ट्री (एक Func<T> भी एक सार फैक्ट्री) इंजेक्शन निर्भरता प्रकार को बदलते हैं। हालांकि, यदि आप ऐसा करते हैं तो यह एक गड़बड़ अमूर्त होगा क्योंकि आप किसी विशेष कार्यान्वयन के ज्ञान को उपभोक्ता के डिज़ाइन को निर्धारित करने की अनुमति देंगे। यह Liskov प्रतिस्थापन सिद्धांत का उल्लंघन करती है।

एक बेहतर विकल्प यह है कि माइस्सर्वी को यह जैसा रखना है , और फिर आश्रितता के लिए एक आवरण बनाएं जो कि विशेष जीवनकाल के मुद्दे को संबोधित करता है:

 public class TransientDependencyWrapper : IDependency { public void DoSomething() { new MyStatefulDependency().DoSomething(); } } 

मूल कार्यान्वयन (माइस्टेटिबल डिप्रैपेंसी) को सीधे इंजेक्शन देने की बजाय MyService में इंजेक्ट करें

यदि आप निर्भरता की रचना को दूर करना चाहते हैं, तो आप हमेशा इस स्तर पर एक सार फैक्ट्री को इंजेक्ट कर सकते हैं।

ऐसा प्रतीत होता है कि आपको एक प्रदाता / कारखाना इंजेक्ट करना चाहिए। आप कैसे प्रतिनिधित्व करते हैं कि आप (और आपके आईओसी का समर्थन करते हैं) – यह उतना आसान हो सकता है जैसे:

 public MyService(Func<IDependency> dependencyProvider) { this.dependencyProvider = dependencyProvider; } public Message Method1() { IDependency dependency = dependencyProvider(); dependency.DoSomething(); } 

… या आपके इस विशिष्ट कारखाने के प्रकार, या सामान्य IFactory<T> आदि के लिए एक इंटरफ़ेस हो सकता है। सभी प्रकार की संभावनाएं हैं – लेकिन मुख्य बिट यह है कि आप जो जरूरत IFactory<T> हैं, इस मामले में "ए प्रत्येक कॉल पर IDependency का एक नया कार्यान्वयन करने का IDependency "।

यदि आपको इंजेक्ट किए गए प्रकार के कई उदाहरण बनाने की आवश्यकता है, तो आपको इसके बजाय एक IDependencyFactory इंजेक्ट करना होगा, जो कि उदाहरण IDependencyFactory को नियंत्रित करने के लिए उत्तरदायी होगा:

 interface IDependencyFactory { IDependency GetInstance(); } 

आप ऐसा कर सकते हैं:

 private readonly Func<IDependancy> _dependancy; public MyService(Func<IDependancy> dependancy) { _dependancy = dependancy; } public Message Method1() { _dependancy().DoSomething(); } public Message Method2() { _dependancy().DoSomething(); } public Message Method3() { _dependancy().DoSomething(); } 

और तब:

 var service = new MyService(() => new SomeConcreteDependency()); service.Method1(); service.Method2(); service.Method3(); 

मेरे दिमाग में आने वाले पहले दो विचार हैं

  1. इसे कन्स्ट्रक्टर पर न लें, लेकिन इसे प्रत्येक विधि पर ले लें।
  2. कंस्ट्रक्टर में एक उदाहरण को Func<IDependency> बजाय, एक फैक्ट्री या Func<IDependency> जो कि जब आप फ़ंक्शन को कॉल करते हैं तो एक नया इंस्टेंस Func<IDependency>