2009-11-06 13 views
9

संतुष्ट करेगा यह मैं क्या डि कंटेनर से चाहते हैं: ब्याज कीकौन सा डि कंटेनर इस

public class Class 
{ 
    public Class(IDependency dependency, string data) { } 
} 

var obj = di.Resolve<Class>(() => new Class(null, "test")); 

अंक:

  1. निर्माता में दोनों निर्भरता और डेटा को हल कर सकते हैं।
  2. कन्स्ट्रक्टर पैरामीटर पास करने के लिए टाइप-सेफ सिंटैक्स का उपयोग कर सकते हैं (सटीक वाक्यविन्यास भिन्न हो सकता है)। हां मैं कन्स्ट्रक्टर तर्क प्राप्त कर सकता हूं (अभिव्यक्ति.बॉडी न्यूएक्सप्रेस के रूप में) - लेकिन मुझे यह पता लगाने के लिए एक तरीका चाहिए कि कंटेनर में कौन से तर्क पंजीकृत हैं।

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

इसके अलावा, संपत्ति इंजेक्शन कभी-कभी उपयोगी हो सकती है, लेकिन यह वैकल्पिक है।

प्रश्न वास्तव में सुविधाओं के संयोजन के बारे में है - उनमें से सभी - टाइप-सुरक्षित, पैरामीटर, स्वचालित पिक-अप ... एक सुविधा की जांच करना आसान है, लेकिन उनमें से एक संयोजन सत्यापित करना आसान नहीं है जब तक कि कोई विशेष कंटेनर से परिचित न हो और इसकी विशेषताओं को जानता हो। इस प्रकार सवाल।

+0

मुझे नहीं लगता कि ऐसा कोई कंटेनर है जो उस तरह के वाक्यविन्यास का समर्थन करता है। लेकिन कई (लगभग सभी) कंटेनर स्पष्ट कंटेनर पैरामीटर का समर्थन करते हैं, और शायद क्लीनर सिंटैक्स के साथ। –

+0

"शायद" उत्तर नहीं है ... जहां तक ​​मुझे पता है कि मैं पैरामीटर की ऑब्जेक्ट [] सरणी पास कर सकता हूं लेकिन यह स्पष्ट रूप से टाइप-सुरक्षित नहीं है ... मैं पैरामीटर ऑर्डर बदल सकता हूं और रनटाइम तक इसके बारे में नहीं जानूंगा । – queen3

+0

क्लीनर द्वारा मेरा मतलब था कि आपको अपने कोड में सीटीआर का स्पष्ट रूप से उपयोग करने की आवश्यकता नहीं है, जैसा कि आप ऊपर करते हैं। आपने जो लिखा है उसके बजाए, क्यों नहीं: 'var obj = new class (di.Resolve ()," test ");'? –

उत्तर

27

मुझे लगता है कि आप एक सार फैक्ट्री को परिभाषित करके बेहतर हो जाएंगे जो आपकी कक्षा बना सकती है।

public interface IFactory 
{ 
    MyClass Create(string data); 
} 

फिर आप इस तरह IFactory के एक कार्यान्वयन बना सकते हैं:

public class MyFactory : IFactory 
{ 
    private IDependency dependency; 

    public MyFactory(IDependency dependency) 
    { 
     if (dependency == null) 
     { 
      throw new ArgumentNullException("dependency"); 
     } 

     this.dependency = dependency; 
    } 

    #region IFactory Members 

    public MyClass Create(string data) 
    { 
     return new MyClass(this.dependency, data); 
    } 

    #endregion 
} 

अपने कंटेनर में, तुम दोनों MyFactory और IDependency के कार्यान्वयन रजिस्टर होगा।

अब आप वर्ग पाने के लिए फैक्टरी, और फैक्टरी को हल करने कंटेनर का उपयोग कर सकते हैं:

var mc = container.Resolve<IFactory>().Create(data); 

यह दृष्टिकोण पूरी तरह से टाइप-सुरक्षित है और अच्छी तरह से चलाने के समय आवेदन डेटा से निर्भरता अलग करता।

+0

बिल्कुल! ..................... –

+7

सार फैक्टरी नाम से इसे कॉल करने के लिए बोनस अंक, लेकिन एक इंटरफेस का उपयोग कर।मैंने बहुत से लोगों को देखा है कि जब वे * सार * फैक्टरी सुनते हैं तो सीधे मूल श्रेणी में जाते हैं। –

+2

हां, मुझे यह पता है, हालांकि मेरे मामले में मैं संकोच करता हूं क्योंकि सरल मामलों के लिए यह इंटरफ़ेस, फैक्ट्री, फैक्ट्री के कंस्ट्रक्टर, विधि बनाएं आदि के साथ कन्स्ट्रक्टर को डुप्लिकेट करने के लिए अधिक है। जटिल मामलों के लिए अच्छा है, लेकिन यह सरल चीजों के लिए भी "डी विस्फोट" है। सोच। और सवाल स्वचालित पंजीकरण डी कंटेनर के बारे में बनी हुई है। – queen3

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