दिलचस्प पोस्ट
पायथन फ़्लोटिंग प्वाइंट अनियमित परिशुद्धता उपलब्ध है? तेजी से आईपी पता कैसे प्राप्त करें I क्या आप मोंगो में $ addToSet के लिए एक कुंजी निर्दिष्ट कर सकते हैं? एक स्ट्रिंग में सबप्रोसेस का पॉप आउट कॉल करें क्या Haskell पूंछ-पुनरावर्ती अनुकूलन है? JQuery के साथ तत्व सामग्री परिवर्तन का पता लगाएं एंड्रॉइड मैप्स प्वाइंट क्लस्टरिंग जब मैं पहली बार एक दृश्य को माप सकता हूँ? UITextView में प्लेसहोल्डर जावास्क्रिप्ट में सरणी आभासी संकेतन क्या है और इसका उपयोग कब करना चाहिए? निष्क्रिय यूनियन सदस्य और अपरिभाषित व्यवहार तक पहुंच? जावा में इस और वर्ग का अर्थ गतिशील रूप से एक स्थानीय चर बनाने के लिए कैसे? एक मॉलोक "डबल फ्री" त्रुटि का कारण कैसे खोजता है? सापेक्ष पथ और जावास्क्रिप्ट में पूर्ण पथ के बीच का अंतर

सीधी डीआई कोड के विरोध में मुझे आईओसी कंटेनर की आवश्यकता क्यों है?

मैं थोड़ी देर के लिए निर्भरता इंजेक्शन (डीआई) का उपयोग कर रहा हूं, या तो कंस्ट्रक्टर, प्रॉपर्टी या विधि में इंजेक्शन कर रहा हूं। मुझे कंट्रोल (आईओसी) कंटेनर का उलटा इस्तेमाल करने की आवश्यकता महसूस नहीं हुई है हालांकि, जितना मैं पढ़ता हूं, IoC कंटेनर का उपयोग करने के लिए समुदाय से अधिक दबाव महसूस करता हूं।

मैंने स्ट्रैटेकमैप , एनआईएनजेक्ट , यूनिटी , और फनक जैसे नेट कंटिनर के साथ खेला। मैं अब भी यह देखने में विफल रहता हूं कि आईओसी कंटेनर मेरे कोड को कैसे लाभ / सुधारने वाला है।

मुझे काम पर कंटेनर का उपयोग करना शुरू करने से भी डर लगता है क्योंकि मेरे कई सहकर्मियों को वह कोड दिखाई देगा, जो उन्हें समझ नहीं आते हैं। उनमें से कई नई तकनीक सीखने में नाखुश हो सकते हैं

कृपया, मुझे आश्वस्त करें कि मुझे आईओसी कंटेनर का उपयोग करने की आवश्यकता है मैं इन तर्कों का उपयोग करने जा रहा हूं जब मैं काम पर अपने साथी डेवलपर्स से बात करता हूँ।

वेब के समाधान से एकत्रित समाधान "सीधी डीआई कोड के विरोध में मुझे आईओसी कंटेनर की आवश्यकता क्यों है?"

वाह, यह विश्वास नहीं हो सकता कि जोएल इस पर पक्षपाती होंगे:

var svc = new ShippingService(new ProductLocator(), new PricingService(), new InventoryService(), new TrackingRepository(new ConfigProvider()), new Logger(new EmailLogger(new ConfigProvider()))); 

इस पर:

 var svc = IoC.Resolve<IShippingService>(); 

कई लोगों को यह नहीं पता है कि आपकी निर्भरता श्रृंखला नेस्टेड बन सकती है, और इसे मैन्युअल रूप से तार करने के लिए जल्दी से बोझ उठाना पड़ता है। यहां तक ​​कि कारखानों के साथ, आपके कोड की नकल बस इसके लायक नहीं है

आईओसी कंटेनर जटिल हो सकते हैं, हाँ। लेकिन इस सरल मामले के लिए मैंने दिखाया है कि यह अविश्वसनीय रूप से आसान है


ठीक है, चलो यह और भी अधिक औचित्यपूर्ण है। मान लीजिए आपके पास कुछ संस्थाएं या मॉडल ऑब्जेक्ट हैं जो आप स्मार्ट UI पर बाँधना चाहते हैं। यह स्मार्ट यूआई (हम इसे सिंडॉज़ गड़बड़ कहते हैं) चाहता है कि आप INOETifyPropertyChanged को लागू करें ताकि वह ट्रैकिंग ट्रैकिंग और यूआई को तदनुसार अपडेट कर सके।

"ठीक है, यह बहुत मुश्किल नहीं है" तो आप लिखना शुरू करें

आप इस के साथ शुरू:

 public class Customer { public string FirstName { get; set; } public string LastName { get; set; } public DateTime CustomerSince { get; set; } public string Status { get; set; } } 

..और इस के साथ अंत:

 public class UglyCustomer : INotifyPropertyChanged { private string _firstName; public string FirstName { get { return _firstName; } set { string oldValue = _firstName; _firstName = value; if(oldValue != value) OnPropertyChanged("FirstName"); } } private string _lastName; public string LastName { get { return _lastName; } set { string oldValue = _lastName; _lastName = value; if(oldValue != value) OnPropertyChanged("LastName"); } } private DateTime _customerSince; public DateTime CustomerSince { get { return _customerSince; } set { DateTime oldValue = _customerSince; _customerSince = value; if(oldValue != value) OnPropertyChanged("CustomerSince"); } } private string _status; public string Status { get { return _status; } set { string oldValue = _status; _status = value; if(oldValue != value) OnPropertyChanged("Status"); } } protected virtual void OnPropertyChanged(string property) { var propertyChanged = PropertyChanged; if(propertyChanged != null) propertyChanged(this, new PropertyChangedEventArgs(property)); } public event PropertyChangedEventHandler PropertyChanged; } 

यह घृणित पाइपिंग कोड है, और मुझे लगता है कि यदि आप कोड लिख रहे हैं जैसे हाथ से आप अपने ग्राहक से चोरी कर रहे हैं काम करने का बेहतर, चालाक तरीका है

कभी वह शब्द सुनना, होशियार काम करना कठिन नहीं है?

अच्छी तरह से सोचो आपकी टीम में कुछ स्मार्ट लड़के आए और कहा: "यह आसान तरीका है"

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

आप जिस IoC उपकरण का उपयोग कर रहे हैं उसके आधार पर, आप ऐसा कुछ कर सकते हैं जो इस तरह दिखता है:

 var bindingFriendlyInstance = IoC.Resolve<Customer>(new NotifyPropertyChangedWrapper()); 

Poof! उस मैन्युअल INotifyPropertyChanged बीएस के सभी प्रश्नों में ऑब्जेक्ट के प्रत्येक वर्चुअल प्रॉपर्टी सेटर पर स्वचालित रूप से आपके लिए जेनरेट होते हैं।

यह जादू है? हाँ ! यदि आप इस तथ्य पर भरोसा कर सकते हैं कि यह कोड उसकी नौकरी करता है, तो आप सुरक्षित रूप से सभी संपत्तियों को लपेटने वाले मुम्बो-जंबो को छोड़ सकते हैं। आपके पास हल करने के लिए व्यावसायिक समस्याएं हैं

एओपी करने के लिए आईओसी टूल के कुछ अन्य रोचक उपयोग:

  • घोषणात्मक और नेस्टेड डेटाबेस लेनदेन
  • काम की घोषणात्मक और नेस्टेड इकाई
  • लॉगिंग
  • पूर्व / पोस्ट की शर्तें (अनुबंध द्वारा डिजाइन)

मैं तुम्हारे साथ हूँ, वादिम आईओसी कंटेनर एक साधारण, सुरुचिपूर्ण, और उपयोगी अवधारणा लेते हैं, और 200-पृष्ठ मैनुअल के साथ आपको दो दिनों तक पढ़ना पड़ता है।

मैं व्यक्तिगत रूप से परेशान हूं कि आईओसी समुदाय ने मार्टिन फोवेल द्वारा एक खूबसूरत, सुरुचिपूर्ण लेख कैसे लिया और 200-300 पेज मैनुअल के साथ जटिल फ्रेमवर्क के एक गुच्छा में इसे बदल दिया।

मैं निर्णय नहीं होने की कोशिश करता हूं (हैहा!), लेकिन मुझे लगता है कि जो लोग आईओसी कंटेनरों का इस्तेमाल करते हैं वह बहुत ही स्मार्ट हैं और (बी) उन लोगों के लिए सहानुभूति की कमी है, जो स्मार्ट नहीं हैं। सब कुछ उन्हें समझ में आता है, इसलिए उन्हें समझने में परेशानी होती है कि कई साधारण प्रोग्रामर्स को भ्रमित करने वाले अवधारणाओं को मिलेगा। यह ज्ञान का अभिशाप है जो लोग IoC कंटेनरों को समझते हैं उन्हें इस बात पर विश्वास करने में परेशानी होती है कि ऐसे लोग हैं जो इसे समझ नहीं पाते हैं।

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

मेरा मानना ​​है कि यदि आप आईओसी कंटेनरों का उपयोग करते हैं, तो आपका कोड स्पष्ट हो जाता है, पढ़ने में बहुत कठिन होता है आपके द्वारा यह पता लगाने की ज़रुरत है कि कोड क्या करने का प्रयास कर रहा है, कम से कम एक से बढ़ जाता है और स्वर्ग में कहीं एक स्वर्गदूत रोता है

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

यदि आपका सिस्टम जटिलता का एक स्तर तक पहुंचता है जहां मैनुअल डी एक घर का काम हो जाता है (जो है, रखरखाव बढ़ता है), तो यह है कि डि कंटेनर फ्रेमवर्क की टीम सीखने की वक्र के खिलाफ।

यदि आप निर्भरता आजीवन प्रबंधन पर अधिक नियंत्रण की आवश्यकता (यानी, अगर आपको सिंगलटन पैटर्न लागू करने की आवश्यकता महसूस होती है), डि कंटेनर देखें

यदि आप डि कंटेनर का उपयोग करते हैं, तो केवल आपके द्वारा आवश्यक सुविधाओं का उपयोग करें XML विन्यास फाइल को छोड़ें और इसे कोड में कॉन्फ़िगर करें यदि यह पर्याप्त है निर्माता इंजेक्शन के लिए छड़ी। यूनिटी या स्ट्रक्चरमैप की मूल बातें कुछ पृष्ठों तक सीमित हो सकती हैं।

इस पर मार्क सीमैन द्वारा एक महान ब्लॉग पोस्ट है: डि डि कंटेनर का उपयोग कब किया जाए

मेरी राय में आईओसी का नंबर एक लाभ आपकी निर्भरता के विन्यास को केंद्रीकृत करने की क्षमता है।

यदि आप वर्तमान में निर्भरता इंजेक्शन का उपयोग कर रहे हैं तो आपका कोड इस तरह दिखाई देगा

 public class CustomerPresenter { public CustomerPresenter() : this(new CustomerView(), new CustomerService()) {} public CustomerPresenter(ICustomerView view, ICustomerService service) { // init view/service fields } // readonly view/service fields } 

अगर आप स्थिर आईओसी कक्षा का इस्तेमाल करते हैं, तो आईएमएचओ जितना अधिक भ्रामक, विन्यास फाइलों का विरोध करता है, आप ऐसा कुछ कर सकते हैं:

 public class CustomerPresenter { public CustomerPresenter() : this(IoC.Resolve<ICustomerView>(), IoC.Resolve<ICustomerService>()) {} public CustomerPresenter(ICustomerView view, ICustomerService service) { // init view/service fields } // readonly view/service fields } 

फिर, आपका स्टेटिक आईओसी क्लास इस तरह दिखेगा, मैं यहाँ एकता का उपयोग कर रहा हूं।

 public static IoC { private static readonly IUnityContainer _container; static IoC() { InitializeIoC(); } static void InitializeIoC() { _container = new UnityContainer(); _container.RegisterType<ICustomerView, CustomerView>(); _container.RegisterType<ICustomerService, CustomerService>(); // all other RegisterTypes and RegisterInstances can go here in one file. // one place to change dependencies is good. } } 

आईओसी कंटेनर गहरी नीडिंत वर्ग निर्भरताओं को लोड करने के लिए भी अच्छे हैं I उदाहरण के लिए यदि आपके पास डीपेंसीेंसी इंजेक्शन का उपयोग करते हुए निम्न कोड था।

 public void GetPresenter() { var presenter = new CustomerPresenter(new CustomerService(new CustomerRepository(new DB()))); } class CustomerPresenter { private readonly ICustomerService service; public CustomerPresenter(ICustomerService service) { this.service = service; } } class CustomerService { private readonly IRespository<Customer> repository; public CustomerService(IRespository<Customer> repository) { this.repository = repository; } } class CustomerRepository : IRespository<Customer> { private readonly DB db; public CustomerRepository(DB db) { this.db = db; } } class DB { } 

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

उदाहरण के लिए:

 public static IoC { private IUnityContainer _container; static IoC() { InitializeIoC(); } static void InitializeIoC() { _container = new UnityContainer(); _container.RegisterType<ICustomerService, CustomerService>(); _container.RegisterType<IRepository<Customer>, CustomerRepository>(); } static T Resolve<T>() { return _container.Resolve<T>(); } } public void GetPresenter() { var presenter = IoC.Resolve<CustomerPresenter>(); // presenter is loaded and all of its nested child dependencies // are automatically injected // - // Also, note that only the Interfaces need to be registered // the concrete types like DB and CustomerPresenter will automatically // resolve. } 

मैं घोषणात्मक प्रोग्रामिंग का एक प्रशंसक हूं (देखें कि मैं कितने एसक्यूएल प्रश्नों का उत्तर देता हूं), लेकिन आईओसी कंटेनर मैंने अपने अच्छे अच्छे के लिए बहुत ही मनोरम लगते देखा है।

… या शायद आईओसी कंटेनरों के डेवलपर्स स्पष्ट दस्तावेज लिखने में असमर्थ हैं।

… या फिर दोनों एक डिग्री या किसी अन्य के लिए सही हैं

मुझे नहीं लगता कि आईओसी कंटेनर की अवधारणा खराब है। लेकिन कार्यान्वयन दोनों शक्तिशाली (अर्थात, लचीला) पर्याप्त अनुप्रयोगों में उपयोगी होने के लिए पर्याप्त होना चाहिए, फिर भी सरल और आसानी से समझा जाता है।

यह संभवतः छह में से छह और दूसरे का आधा दर्जन है असली आवेदन (एक खिलौना या डेमो नहीं) जटिल होना जरूरी है, कई कोने वाले मामलों के लिए लेखांकन और अपवाद-से- नियम या तो आप अनिवार्य कोड में जटिलता को परिभाषित करते हैं, या फिर घोषणात्मक कोड में। लेकिन आपको इसे कहीं और का प्रतिनिधित्व करना होगा

एक कंटेनर का उपयोग करना प्रारंभिक रूप से अनिवार्य / पटकथा वाली शैली से बदलना और एक घोषणात्मक एक से कॉन्फ़िगरेशन के बारे में है। इसमें कुछ अलग फायदेमंद प्रभाव हो सकते हैं:

  • हेयरबॉल मुख्य कार्यक्रम स्टार्टअप दिनचर्या कम करना
  • काफी गहरा परिनियोजन समय कॉन्फ़िगरेशन क्षमताओं को सक्षम करना
  • निर्भरता-इंजेक्शन शैली को नए काम के लिए कम से कम प्रतिरोध का रास्ता बनाना।

बेशक, कुछ मुश्किलें हो सकती हैं:

  • संहिता के लिए जटिल स्टार्टअप / शटडाउन / लाइफसाइकिल प्रबंधन की आवश्यकता होती है, वह आसानी से एक कंटेनर में अनुकूलित नहीं हो सकती है।
  • संभवत: आपको किसी भी निजी, प्रक्रिया और टीम संस्कृति के मुद्दों को नेविगेट करना होगा – लेकिन तब, आपने क्यों पूछा …
  • कुछ टूलकिट तेजी से हेवीवेट खुद बनते जा रहे हैं, जिससे गहरी निर्भरता को प्रोत्साहित किया जा सकता है कि कई डि कंटेनरों के खिलाफ प्रतिक्रिया के रूप में शुरू हो गया।

यह मुझे लगता है जैसे आपने पहले से ही अपना आईओसी कंटेनर बनाया है (मार्टिन फोवेल द्वारा वर्णित विभिन्न पैटर्नों का उपयोग करके) और पूछ रहे हैं कि किसी और के कार्यान्वयन आपके द्वारा क्यों बेहतर है।

इसलिए, आपके पास पहले से ही काम करने वाले कोड का एक गुच्छा है और सोच रहे हैं कि आप इसे किसी और के कार्यान्वयन के साथ क्यों बदलना चाहते हैं।

तीसरे पक्ष के आईओसी कंटेनर पर विचार करने के लिए पेशेवरों

  • आप मुफ्त में बग तय की गई हैं
  • पुस्तकालय डिजाइन तुम्हारा से बेहतर हो सकता है
  • लोग पहले से ही विशेष पुस्तकालय से परिचित हो सकते हैं
  • लाइब्रेरी आपकी तुलना में तेज़ हो सकता है
  • इसमें कुछ विशेषताएं हो सकती हैं जिन्हें आप चाहते थे कि आपने कार्यान्वित किया लेकिन कभी समय नहीं था (क्या आपके पास एक सेवा स्थान है?)

विपक्ष

  • आपको मुफ़्त मुड़कर कीड़े मिलती हैं 🙂
  • पुस्तकालय डिजाइन तुम्हारा से भी बदतर हो सकता है
  • आपको एक नया एपीआई सीखना होगा
  • आप कभी भी उपयोग नहीं करेंगे कई विशेषताएं
  • आमतौर पर यह कोड डीबग करना कठिन होता है जिसे आपने नहीं लिखा था
  • पिछले आईओसी कंटेनर से प्रवास करना कठिन हो सकता है

तो, अपने पक्ष के खिलाफ अपने पक्ष का वजन और एक निर्णय करें।

मुझे लगता है कि डीओ का उपयोग करके आईओसी के अधिकांश मूल्य में वृद्धि हुई है चूंकि आप पहले से ही ऐसा कर रहे हैं, बाकी का लाभ बढ़ता है

आपके द्वारा प्राप्त होने वाला मूल्य उस आवेदन के प्रकार पर निर्भर करेगा जो आप पर काम कर रहे हैं:

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

  • विस्तार के कई बिंदुओं के साथ, आईओसी का इस्तेमाल विन्यास से घटकों को लोड करने के लिए किया जा सकता है। यह एक आम बात है, लेकिन कंटेनर द्वारा उपकरण उपलब्ध कराए जाते हैं।

  • यदि आप कुछ क्रॉस-कटिंग चिंताओं के लिए एओपी का उपयोग करना चाहते हैं, तो आईओसी विधि आविष्कारों को रोकने के लिए हुक प्रदान करता है । परियोजनाओं पर यह सामान्यतः कम किया जाता है लेकिन आईओसी इसे आसान बनाता है।

मैंने पहले इस तरह की कार्यक्षमता लिखी है लेकिन अगर मुझे इन सुविधाओं में से किसी की ज़रूरत है तो मैं एक पूर्व-निर्मित और परीक्षण उपकरण का उपयोग करना चाहूंगा अगर यह मेरी वास्तुकला को फिट करे

जैसा कि अन्य लोगों द्वारा उल्लिखित है, आप केंद्र को भी कॉन्फ़िगर कर सकते हैं कि आप किस कक्षा का उपयोग करना चाहते हैं। यद्यपि यह एक अच्छी बात हो सकती है, यह गलत दिशा और जटिलता की कीमत पर आता है। अधिकतर अनुप्रयोगों के मुख्य घटकों को बहुत ज्यादा नहीं बदला जाता है, इसलिए व्यापार-बंद करना कठिन होता है।

मैं एक आईओसी कंटेनर का उपयोग करता हूँ और कार्यक्षमता की सराहना करता हूं, लेकिन मुझे यह स्वीकार करना होगा कि मैंने ट्रेड-ऑफ पर ध्यान दिया है: मेरा कोड कक्षा स्तर पर अधिक स्पष्ट हो जाता है और आवेदन स्तर पर कम स्पष्ट होता है (यानी नियंत्रण प्रवाह दृश्यता)।

मैं आईओसी की आशंका को ठीक कर रहा हूं। मैं इन दिनों ज्यादातर मामलों में डीआई के लिए आईओसी का इस्तेमाल करना उचित समझता हूं। आईओसी कंटेनर बलिदान समय की जांच संकलन और माना जाता है कि बदले में आप "आसान" सेटअप, जटिल जीवन भर प्रबंधन और रन समय पर निर्भरता की खोज पर उड़ने पर। मुझे समय की जांच करने और समय-समय पर जादू / अपवादों को संकलित करने के नुकसान का पता चलता है, अधिकांश मामलों में घंटियाँ और सीटी के लायक नहीं है। बड़े उद्यम अनुप्रयोगों में वे क्या चल रहा है उसका पालन करना बहुत मुश्किल बना सकते हैं।

मैं केंद्रीकरण तर्क नहीं खरीदता हूं क्योंकि आप स्थिर सेटअप को बहुत आसानी से केन्द्रित कर सकते हैं और साथ ही आपके आवेदन के लिए एक सार कारखाने का उपयोग कर सकते हैं और वस्तु के निर्माण को धार्मिक फैसले के रूप में समझा सकते हैं यानी उचित डीआई।

स्थिर मैजिक-फ्री डि जैसे क्यों नहीं:

 interface IServiceA { } interface IServiceB { } class ServiceA : IServiceA { } class ServiceB : IServiceB { } class StubServiceA : IServiceA { } class StubServiceB : IServiceB { } interface IRoot { IMiddle Middle { get; set; } } interface IMiddle { ILeaf Leaf { get; set; } } interface ILeaf { } class Root : IRoot { public IMiddle Middle { get; set; } public Root(IMiddle middle) { Middle = middle; } } class Middle : IMiddle { public ILeaf Leaf { get; set; } public Middle(ILeaf leaf) { Leaf = leaf; } } class Leaf : ILeaf { IServiceA ServiceA { get; set; } IServiceB ServiceB { get; set; } public Leaf(IServiceA serviceA, IServiceB serviceB) { ServiceA = serviceA; ServiceB = serviceB; } } interface IApplicationFactory { IRoot CreateRoot(); } abstract class ApplicationAbstractFactory : IApplicationFactory { protected abstract IServiceA ServiceA { get; } protected abstract IServiceB ServiceB { get; } protected IMiddle CreateMiddle() { return new Middle(CreateLeaf()); } protected ILeaf CreateLeaf() { return new Leaf(ServiceA,ServiceB); } public IRoot CreateRoot() { return new Root(CreateMiddle()); } } class ProductionApplication : ApplicationAbstractFactory { protected override IServiceA ServiceA { get { return new ServiceA(); } } protected override IServiceB ServiceB { get { return new ServiceB(); } } } class FunctionalTestsApplication : ApplicationAbstractFactory { protected override IServiceA ServiceA { get { return new StubServiceA(); } } protected override IServiceB ServiceB { get { return new StubServiceB(); } } } namespace ConsoleApplication5 { class Program { static void Main(string[] args) { var factory = new ProductionApplication(); var root = factory.CreateRoot(); } } //[TestFixture] class FunctionalTests { //[Test] public void Test() { var factory = new FunctionalTestsApplication(); var root = factory.CreateRoot(); } } } 

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

लाभ:

  • सभी सेटअप और ऑब्जेक्ट सृजन कॉन्फ़िगरेशन को केंद्रीकृत किया गया है।
  • विन्यास सिर्फ कोड है
  • समय जांच को संकलित करना आसान बनाए रखता है क्योंकि आप अपने पंजीकरण अपडेट करने के लिए नहीं भूल सकते।
  • कोई रन-टाइम प्रतिबिंब जादू नहीं है

मैं संदेह करता हूं कि इसे अगले हरे फील्ड प्रोजेक्ट पर जाने के लिए और ईमानदारी से अपने आप से पूछें कि आप किस बिंदु पर कंटेनर की ज़रूरत है आईओसी कंटेनर में बाद में यह कारक होना आसान है क्योंकि आप बस IOC कंटेनर कॉन्फ़िगरेशन मॉड्यूल के साथ एक फैक्ट्री कार्यान्वयन की जगह ले रहे हैं।

मेरे लिए आईओसी कंटेनर (व्यक्तिगत तौर पर, मैं निन्ग का उपयोग करता हूं) का उपयोग करने का सबसे बड़ा लाभ है कि सेटिंग के चारों ओर पार करने और वैश्विक राज्य वस्तुओं के अन्य प्रकारों को समाप्त करने के लिए किया गया है।

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

आईओसी कंटेनर के उपयोग के बिना मुझे 2, 3, …, n ऑब्जेक्ट्स के जरिए सेटिंग्स और / या मेटाडेटा को पास करना होगा, वास्तव में उस ऑब्जेक्ट द्वारा उपयोग किए जाने से पहले यह आवश्यक था।

डीआई / आईओसी कंटेनर के कई अन्य लाभ हैं क्योंकि अन्य लोगों ने यहां विवरण दिया है और वस्तुओं के अनुरोध करने के लिए वस्तुओं को बनाने के विचार से आगे बढ़ना मन-झुकाव हो सकता है, लेकिन डी का प्रयोग करके मुझे और मेरी टीम के लिए बहुत मददगार था इसलिए आप इसे जोड़ सकते हैं अपने शस्त्रागार को!

IoC चौखटे उत्कृष्ट हैं यदि आप चाहते हैं …

  • … दूर प्रकार सुरक्षा फेंक दो। कई (सभी?) IoC फ्रेमवर्क आपको कोड निष्पादित करने के लिए मजबूर करते हैं यदि आप चाहते हैं कि कुछ चीजें सही तरीके से आदी हो जाएं "हे! आशा है कि मुझे सब कुछ स्थापित किया गया है, इसलिए इन 100 वर्गों के मेरे प्रारंभिक उत्पादन में असफल नहीं होंगे, शून्य-सूचक अपवाद फेंक देंगे!"

  • … ग्लोबल्स के साथ आपका कोड कूड़ा (आईओसी चौखटे सभी वैश्विक राज्यों को बदलने के बारे में हैं)।

  • … अस्पष्ट निर्भरता के साथ गंदे कोड लिखिए, जो रिफ़ैक्टर के लिए कठिन है क्योंकि आपको कभी नहीं पता होगा कि क्या क्या है पर निर्भर करता है

आईओसी के साथ समस्या यह है कि जो लोग उनका इस्तेमाल करते हैं वे इस प्रकार कोड लिखने के लिए इस्तेमाल करते हैं

 public class Foo { public Bar Apa {get;set;} Foo() { Apa = new Bar(); } } 

जो स्पष्ट रूप से दोषपूर्ण है क्योंकि फू और बार के बीच निर्भरता कठिन-वायर्ड है। फिर उन्हें एहसास हुआ कि यह कोड लिखना बेहतर होगा

 public class Foo { public IBar Apa {get;set;} Foo() { Apa = IoC<IBar>(); } } 

जो भी दोषपूर्ण है, लेकिन कम स्पष्ट रूप से इतना। हस्केल्ले में Foo() का प्रकार IO Foo लेकिन आप वास्तव में IO -part नहीं चाहते हैं और यह एक चेतावनी संकेत होना चाहिए कि अगर आपको यह मिला है तो आपके डिज़ाइन में कुछ गलत है।

इसे से छुटकारा पाने के लिए (आईओ-भाग), IoC-frameworks के सभी फायदे प्राप्त करें और इसमें कोई भी कमियां नहीं हैं जो आप एक अमूर्त कारखाने का उपयोग कर सकते हैं।

सही समाधान कुछ ऐसा होगा

 data Foo = Foo { apa :: Bar } 

या हो सकता है

 data Foo = forall b. (IBar b) => Foo { apa :: b } 

और इंजेक्शन (लेकिन मैं इसे इंजेक्ट नहीं करता) बार

इसके अलावा: एरिक मेजिर (LINQ के आविष्कारक) के साथ इस वीडियो को देखें जहां वे कहते हैं कि डि उन लोगों के लिए है जो गणित नहीं जानते (और मैं इससे सहमत नहीं हो सकता): http://www.youtube.com/watch?v = 8Mttjyf-8P4

Unlike Mr. Spolsky I don't believe that people who use IoC-frameworks are very smart – I simply believe they don't know math.

I've found that correctly implementing Dependency Injection tends to force programmers to use a variety of other programming practices that help to improve the testability, flexibility, maintainability, and scalability of code: practices like the Single Responsibility Principle, Separations of Concerns, and coding against APIs. It feels like I'm being compelled to write more modular, bite-sized classes and methods, which makes the code easier to read, because it can be taken in bite-sized chunks.

But it also tends to create rather large dependency trees, which are far more easily managed via a framework (especially if you use conventions) than by hand. Today I wanted to test something really quickly in LINQPad, and I figured it'd be too much bother to create a kernel and load in my modules, and I ended up writing this by hand:

 var merger = new SimpleWorkflowInstanceMerger( new BitFactoryLog(typeof(SimpleWorkflowInstanceMerger).FullName), new WorkflowAnswerRowUtil( new WorkflowFieldAnswerEntMapper(), new ActivityFormFieldDisplayInfoEntMapper(), new FieldEntMapper()), new AnswerRowMergeInfoRepository()); 

In retrospect, it would have been quicker to use the IoC framework, since the modules define pretty much all of this stuff by convention.

Having spent some time studying the answers and comments on this question, I am convinced that the people who are opposed to using an IoC container aren't practicing true dependency injection. The examples I've seen are of practices that are commonly confused with dependency injection. Some people are complaining about difficulty "reading" the code. If done correctly, the vast majority of your code should be identical when using DI by hand as when using an IoC container. The difference should reside entirely in a few "launching points" within the application.

In other words, if you don't like IoC containers, you probably aren't doing Dependency Injection the way it's supposed to be done.

Another point: Dependency Injection really can't be done by hand if you use reflection anywhere. While I hate what reflection does to code navigation, you have to recognize that there are certain areas where it really can't be avoided. ASP.NET MVC, for example, attempts to instantiate the controller via reflection on each request. To do dependency injection by hand, you would have to make every controller a "context root," like so:

 public class MyController : Controller { private readonly ISimpleWorkflowInstanceMerger _simpleMerger; public MyController() { _simpleMerger = new SimpleWorkflowInstanceMerger( new BitFactoryLog(typeof(SimpleWorkflowInstanceMerger).FullName), new WorkflowAnswerRowUtil( new WorkflowFieldAnswerEntMapper(), new ActivityFormFieldDisplayInfoEntMapper(), new FieldEntMapper()), new AnswerRowMergeInfoRepository()) } ... } 

Now compare this with allowing a DI framework to do it for you:

 public MyController : Controller { private readonly ISimpleWorkflowInstanceMerger _simpleMerger; public MyController(ISimpleWorkflowInstanceMerger simpleMerger) { _simpleMerger = simpleMerger; } ... } 

Using a DI framework, note that:

  • I can unit-test this class. By creating a mock ISimpleWorkflowInstanceMerger , I can test that it gets used the way I anticipate, without the need for a database connection or anything.
  • I use far less code, and the code is much easier to read.
  • If one of my dependency's dependency's changes, I don't have to make any changes to the controller. This is especially nice when you consider that multiple controllers are likely to use some of the same dependencies.
  • I never explicitly reference classes from my data layer. My web application can just include a reference to the project containing the ISimpleWorkflowInstanceMerger interface. This allows me to break the application up into separate modules, and maintain a true multi-tier architecture, which in turn makes things much more flexible.

A typical web application will have quite a few controllers. All of the pain of doing DI by hand in each controller will really add up as your application grows. If you have an application with only one context root, which never tries to instantiate a service by reflection, then this isn't as big a problem. Nevertheless, any application that uses Dependency Injection will become extremely expensive to manage once it reaches a certain size, unless you use a framework of some kind to manage the dependency graph.

Whenever you use the "new" keyword, you are creating a concrete class dependency and a little alarm bell should go off in your head. It becomes harder to test this object in isolation. The solution is to program to interfaces and inject the dependency so that the object can be unit tested with anything that implements that interface (eg. mocks).

The trouble is you have to construct objects somewhere. A Factory pattern is one way to shift the coupling out of your POXOs (Plain Old "insert your OO language here" Objects). If you and your co-workers are all writing code like this then an IoC container is the next "Incremental Improvement" you can make to your codebase. It'll shift all that nasty Factory boilerplate code out of your clean objects and business logic. They'll get it and love it. Heck, give a company talk on why you love it and get everyone enthused.

If your co-workers aren't doing DI yet, then I'd suggest you focus on that first. Spread the word on how to write clean code that is easily testable. Clean DI code is the hard part, once you're there, shifting the object wiring logic from Factory classes to an IoC container should be relatively trivial.

Because all the dependencies are clearly visible, it promotes creating components which are loosely coupled and at the same time easily accessible and reusable across the application.

You don't need an IoC container.

But if you're rigorously following a DI pattern, you'll find that having one will remove a ton of redundant, boring code.

That's often the best time to use a library/framework, anyway – when you understand what it's doing and could do it without the library.

I just so happen to be in the process of yanking out home grown DI code and replacing it with an IOC. I have probably removed well over 200 lines of code and replaced it with about 10. Yes, I had to do a little bit of learning on how to use the container (Winsor), but I'm an engineer working on internet technologies in the 21st century so I'm used to that. I probably spent about 20 minutes looking over the how tos. This was well worth my time.

As you continue to decouple your classes and invert your dependencies, the classes continue to stay small and the "dependency graph" continues to grow in size. (This isn't bad.) Using basic features of an IoC container makes wiring up all these objects trivial, but doing it manually can get very burdensome. For example, what if I want to create a new instance of "Foo" but it needs a "Bar". And a "Bar" needs an "A", "B", and "C". And each of those need 3 other things, etc etc. (yes, I can't come up with good fake names 🙂 ).

Using an IoC container to build your object graph for you reduces complexity a ton and pushes it out into one-time configuration. I simply say "create me a 'Foo'" and it figures out what's needed to build one.

Some people use the IoC containers for much more infrastructure, which is fine for advanced scenarios but in those cases I agree it can obfuscate and make code hard to read and debug for new devs.

Dittos about Unity. Get too big, and you can hear the creaking in the rafters.

It never surprises me when folks start to spout off about how clean IoC code looks are the same sorts of folks who at one time spoke about how templates in C++ were the elegant way to go back in the 90's, yet nowadays will decry them as arcane. Bah !

In the .NET world AOP isn't too popular, so for DI a framework is your only real option, whether you write one yourself or use another framework.

If you used AOP you can inject when you compile your application, which is more common in Java.

There are many benefits to DI, such as reduced coupling so unit testing is easier, but how will you implement it? Do you want to use reflection to do it yourself?

So, it's been almost 3 years, eh?

  1. 50% of those who commented in favor of IoC frameworks don't understand the difference between IoC and IoC Frameworks. I doubt they know that you can write code without being deployed to an app server

  2. If we take most popular Java Spring framework, it is IoC configuration moved from XMl into the code and now look like this

`@Configuration public class AppConfig {

 public @Bean TransferService transferService() { return new TransferServiceImpl(accountRepository()); } public @Bean AccountRepository accountRepository() { return new InMemoryAccountRepository(); } 

} ` And we need a framework to do this why exactly?

Honestly I don't find there to be many cases where IoC containers are needed, and most of the time, they just add unneeded complexity.

If you are using it just for making construction of an object simpler, I'd have to ask, are you instantiating this object in more than one location? Would a singleton not suit your needs? Are you changing the configuration at runtime? (Switching data source types, etc).

If yes, then you might need an IoC container. If not, then you're just moving the initialization away from where the developer can easily see it.

Who said that an interface is better than inheritance anyway? Say you're testing a Service. Why not use constructor DI, and create mocks of the dependencies using inheritance? Most services I use only have a few dependencies. Doing unit testing this way prevents maintaining a ton of useless interfaces and means you don't have to use Resharper to quickly find the declaration of a method.

I believe that for most implementations, saying that IoC Containers remove unneeded code is a myth.

First, there's setting up the container in the first place. Then you still have to define each object that needs to be initialized. So you don't save code in initialization, you move it (unless your object is used more than once. Is it better as a Singleton?). Then, for each object you've initialized in this way, you have to create and maintain an interface.

Anyone have any thoughts on this?

You would need an IoC container if you needed to centralize the configuration of your dependencies so that they may be easily swapped out en mass. This makes the most sense in TDD, where many dependencies are swapped out, but where there is little interdependence between the dependencies. This is done at the cost of obfuscating the flow of control of object construction to some degree, so having a well organized and reasonably documented configuration is important. It is also good to have a reason to do this, otherwise, it is mere abstraction gold-plating . I have seen it done so poorly that it was dragged down to being the equivalent to a goto statement for constructors.

Here is why. The project is called IOC-with-Ninject. You can download and run it with Visual Studio. This example uses Ninject but ALL the 'new' statements are in one location and you can completely change how your application runs by changing which bind module to use. The example is set up so you can bind to a mocked version of the services or the real version. In small projects that may not matter, but in big projects it's a big deal.

Just to be clear, advantages as I see them: 1) ALL new statements in one location at root of code. 2) Totally re-factor code with one change. 3) Extra points for 'cool factor' 'cause it's… well: cool. :p

I will try to find why IOC might not be good for from my perspective.

As with everything else, IOC container (or as Einstein would put it I=OC^2) is a concept you have to decide for yourself if you need it or not in your code. Recent fashion outcry about IOC is only that, fashion. Don't fall for fashion, that is first. There are myriads of concepts out there you could implement in your code. First of all, I am using dependency injection since I have started programming, and learned the term itself when it was popularized under that name. Dependency control is a very old subject and it was addressed so far in trillions of ways, depending on what was decoupling from what. Decoupling everything from everything is a nonsense. The problem with IOC container is that it tries to be as useful as Entity Framework or NHibernate. While writing an object-relational mapper is simply a must as soon as you have to couple any database with your system, IOC container is not always necessary. So when IOC container is useful:

  1. When you have a situation with many dependencies you want to organize
  2. When you do not care about coupling your code with third-party product
  3. When your developers want to learn how to work with a new tool

1: It is not that often that you have so many dependencies in your code, or that you are aware of them early in design. Abstract thinking is useful when abstract thinking is due.

2: Coupling your code with third-party code is a HuGe problem. I was working with code that is 10+ years old and that was following at that time fancy and advanced concepts ATL, COM, COM+ and so on. There is nothing you can do with that code now. What I am saying is that an advanced concept gives an apparent advantage, yet this is cancelled on long run with the outdated advantage itself. It just had made all of it more expensive.

3: Software development is hard enough. You can extend it to unrecognizable levels if you allow some advanced concept to crop into your code. There is a problem with IOC2. Although it is decoupling dependencies, it is decoupling the logic flow as well. Imagine you have found a bug and you need to set a break to examine the situation. IOC2, as any other advanced concept, is making that more difficult. Fixing a bug within a concept is more difficult than fixing a bug in a plainer code, because when you fix a bug a concept must be obeyed again. (Just to give you an example, C++ .NET is constantly changing the syntax so much that you need to think hard before you refactor some older version of .NET.) So what is the problem with IOC? The problem is in resolving dependencies. The logic for resolving is commonly hidden in the IOC2 itself, written maybe in uncommon way that you need to learn and maintain. Will your third-party product be there in 5 years? Microsoft's was not.

"We know how" syndrome is written all over the place regarding IOC2. This is similar to automation testing. Fancy term and perfect solution at first glance, you simply put all your tests to execute over night and see the results in the morning. It is really painful to explain company after company what automated testing really means. Automated testing is definitely not a quick way of reducing the number of bugs which you can introduce overnight to increase the quality of your product. But, fashion is making that notion annoyingly dominant. IOC2 suffers the same syndrome. It is believed that you need to implement it in order your software to be good. EvErY recent interview I was asked if I am implementing IOC2 and automation. That is a sign of fashion: the company had some part of code written in MFC they will not abandon.

You need to learn IOC2 as any other concept in software. The decision if IOC2 needs to be used is within the team and the company. However, at least ALL above arguments must be mentioned before the decision is made. Only if you see that plus side outweighs negative side, you can make a positive decision.

There is nothing wrong with IOC2 except that it does solve only the problems it solves and introduces the problems it introduces. और कुछ नहीं। However, going against the fashion is very difficult, they have sweat mouth, the followers of anything. It is strange how none of them is there when the problem with their fanciness becomes apparent. Many concepts in software industry have been defended because they create profit, books are written, conferences held, new products made. That is fashion, usually short lived. As soon as people find something else they abandon it completely. IOC2 is useful but it shows the same signs as many other vanished concepts I have seen. I do not know if it will survive. There is no rule for that. You think if it is useful, it will survive. No, it does not go that way. One big rich company is enough and the concept can die within few weeks. We'll see. NHibernate survived, EF came second. Maybe IOC2 will survive too. Do not forget that most concepts in software development are about nothing special, they are very logical, simple and obvious, and sometimes it is more difficult to remember the current naming convention than to understand the concept itself. Does the knowledge of IOC2 make a developer a better developer? No, because if a developer was not able to come up with a concept similar in nature to IOC2 then it will be difficult for him or her to understand which problem IOC2 is solving, using it will look artificial and he or she may start using it for sake of being some sort of politically correct.

Personally, I use IoC as some sort of structure map of my application (Yeah, I also prefer StructureMap 😉 ). It makes it easy to substitute my ussual interface implementations with Moq implementations during tests. Creating a test setup can be as easy as making a new init-call to my IoC-framework, substituting whichever class is my test-boundary with a mock.

This is probably not what IoC is there for, but it's what I find myself using it for the most..

IOC CONTAINER SOLVES A PROBLEM YOU MIGHT NOT HAVE BUT IT'S A NICE PROBLEM TO HAVE

http://kozmic.net/2012/10/23/ioc-container-solves-a-problem-you-might-not-have-but-its-a-nice-problem-to-have/

you do not need a framework to achieve dependency injection. You can do this by core java concepts as well. http://en.wikipedia.org/wiki/Dependency_injection#Code_illustration_using_Java

I realize this is a rather old post, but it seems to still be reasonably active, and I thought I'd contribute a couple of points that have not yet been mentioned in other answers.

I will say that I agree with the benefits of dependency injection, but I do prefer to construct and manage the objects myself, using a pattern not unlike that outlined by Maxm007 in his answer. I have found two main problems with using 3rd party containers:

1) Having a 3rd party library manage the lifetime of your objects "automagically" can lend itself to unexpected results. We have found that especially in large projects, you can have vastly more copies of an object than you expect, and more than you would if you were manually managing the lifecycles. I'm sure this varies depending on the framework used, but the problem exists nonetheless. This can also be problematic if your object holds resources, data connections, etc., since the object can sometimes live longer than you expect. So inevitably, IoC containers tend to increase the resource utilization and memory footprint of an application.

2) IoC containers, in my opinion, are a form of "black box programming". I have found that in particular, our less experienced developers tend to abuse them. It allows the programmer to not have to think about how objects should relate to each other or how to decouple them, because it provides them with a mechanism in which they can simply grab any object they want out of thin air. Eg, there may be a good design reason that ObjectA should never know about ObjectB directly, but rather than creating a factory or bridge or service locator, an inexperienced programmer will simply say "no problem, I'll just grab ObjectB from the IoC container". This can actually lead to increased object coupling, which is what IoC is supposed to help prevent.

Dependency Injection in an ASP.NET project can be accomplished with a few lines of code. I suppose there is some advantage to using a container when you have an app that uses multiple front ends and needs unit tests.