23

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

public interface IEngine 
{ 
    double MaxSpeed 
    { 
     get; 
    } 
} 

internal class FastEngine:IEngine 
{ 
    public double MaxSpeed 
    { 
     get 
     { 
      return 100d; 
     } 
    } 
} 

internal class SlowEngine:IEngine 
{ 
    public double MaxSpeed 
    { 
     get 
     { 
      return 10d; 
     } 
    } 
} 

public class Car 
{ 
    private IEngine engine; 
    public double MaximumSpeed 
    { 
     get 
     { 
      return this.engine.MaxSpeed; 
     } 
    } 

    public Car(IEngine engine) 
    { 
     this.engine = engine; 
    } 
} 

मेरे समस्या है निम्नलिखित: मैं एक तेजी से कार या एक धीमी गति से कार instantiating के बारे में कैसे जाना चाहिए? मैं प्रत्येक कार्यान्वयन के साथ मुझे प्रदान करने के लिए कंटेनर का उपयोग कर सकते हैं, और मैं उपयोग करने के लिए एक "डिफ़ॉल्ट" कार्यान्वयन सेट कर सकते हैं:

IUnityContainer container = new UnityContainer(); 
container.RegisterType<IEngine, FastEngine>(); 
container.RegisterType<IEngine, FastEngine>("Fast"); 
container.RegisterType<IEngine, SlowEngine>("Slow"); 
var car = container.Resolve<Car>(); 
Assert.AreEqual(100, car.MaximumSpeed); 

लेकिन क्या मैं चाहूँगा की एक विशिष्ट कार्यान्वयन के साथ एक कार का अनुरोध करने में सक्षम होना है रणनीति -

var car = container.Resolve<Car>(??? use "Fast" or "Slow ???); 

क्या मैं ऐसा करने के लिए कंटेनर का उपयोग कर सकता हूं? या क्या मुझे एक फैक्टरी लिखनी चाहिए जो कंटेनर का उपयोग करे? किसी भी मार्गदर्शन की सराहना की जाएगी - मुझे यकीन नहीं है कि मैं इसके बारे में सही सोच रहा हूं!

उत्तर

26

डी में एक आम पैटर्न है कि रन-टाइम पर केवल एक दिए गए अमूर्तता का एक ही कार्यान्वयन होने जा रहा है। यह सिर्फ जीवन को बहुत आसान बनाता है, क्योंकि आपको उस अस्पष्टता से निपटने की आवश्यकता नहीं है जैसे आप वर्णन करते हैं।

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

Abstract Factory शुरू करने के लिए एक बेहतर समाधान होगा जो आपको चाहिए जो प्रदान कर सकता है।

public interface ICarFactory 
{ 
    Car Create(IEngine engine); 
} 

आप अधिक रणनीतियाँ इंजेक्षन करने की जरूरत है की तरह कुछ है, शायद Builder डिजाइन पैटर्न और भी बेहतर फिट हो सकता है।

किसी भी मामले में, बिंदु यह है कि कंटेनर में कई अलग-अलग कारों को पंजीकृत करने के बजाय, आप इसके बजाय एक एकल आईकरफ़ैक्टरी कार्यान्वयन पंजीकृत करेंगे।

अपने क्लाइंट कोड में, आप एक विशेष आईइंजिन के आधार पर कार उदाहरण बनाने के लिए इंजेक्शन आईकरफ़ैक्टरी का उपयोग करेंगे।

var car = factory.Create(engine); 
+0

धन्यवाद, अंतर्दृष्टिपूर्ण उत्तर। मैं रणनीतियों का उपयोग करता हूं, कई रणनीतियों को रन-टाइम पर बदल दिया जाता है, बहुत कुछ; डिफ़ॉल्ट रूप से मैं जो वर्णन करता हूं वह करता हूं (फैक्ट्री या बिल्डर), लेकिन मैंने रणनीति पैटर्न और डी को बहुत कुछ देखा, और हालांकि इससे मदद मिल सकती है। आप जो कहते हैं उससे, ऐसा लगता है कि एक कंटेनर केवल मामूली मददगार होगा। – Mathias

+0

मुझे अभी भी लगता है कि कंटेनर बेहद सहायक हैं। इन मामलों में, वे रणनीति के बजाए कारखाने को इंजेक्ट करेंगे, लेकिन मुझे लगता है कि आप अभी भी कंटेनर के साथ कारखाने को लागू करना चुन सकते हैं ... –

+4

ओह मुझे लगता है कि मैं देखता हूं कि आपका क्या मतलब है; सही कार वापस करने के बजाय, इंजन के आधार पर सही कारखाना वापस करें। किसी भी मामले में, आपकी टिप्पणी फिर से: एक अमूर्तता के लिए एक ही कार्यान्वयन प्रदान करने के लिए उपयोग किए जाने वाले कंटेनर बहुत उपयोगी थे; यह उन उदाहरणों के अनुरूप है जो मैंने देखा, जो कॉन्फ़िगरेशन उन्मुख हैं। उस फ्रेम में, आपके पास एक रणनीति पैटर्न हो सकता है, लेकिन एक विशेष परिनियोजन के पास केवल एक कार्यान्वयन कॉन्फ़िगर किया जाएगा। – Mathias

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