2011-09-06 11 views
9

यह प्रश्न मेरे पिछले प्रश्न का अनुवर्ती है: Autofac: Hiding multiple contravariant implementations behind one compositeऑटोफैक: दोनों प्रकार और बाहर तर्क प्रकारों के साथ वेरिएंट प्रकारों को हल करना

मैं ऑटोफैक के कॉन्वर्सिस और contravariance समर्थन के साथ क्या कर सकता है की सीमाओं को खोजने की कोशिश कर रहा हूं। मैंने देखा कि ऑटोफैक का ContravariantRegistrationSource केवल एक सामान्य जेनेरिक पैरामीटर के साथ जेनेरिक इंटरफेस का समर्थन करता है जो in कीवर्ड के साथ चिह्नित है। ऐसा लगता है कि इस सुविधा की उपयोगिता सीमित है, और मैं सोच रहा हूं कि ऑटोफैक के पास कॉन्वर्सिस और contravariance के समर्थन को बढ़ाने में अन्य तरीके हैं।

मुझे यह स्वीकार करना होगा कि मैं एक असली एप्लिकेशन डिज़ाइन के कारण यह नहीं पूछ रहा हूं। मैं जानबूझ कर शिक्षा के लिए ऑटोफैक की सीमाएं खोजने की कोशिश कर रहा हूं।

public interface IConverter<in TIn, out TOut> 
{ 
    TOut Convert(TIn value); 
} 

और निम्नलिखित कार्यान्वयन:

public class ObjectToStringConverter : IConverter<object, string> 
{ 
    string IConverter<object, string>.Convert(object value) 
    { 
     return value.ToString(); 
    } 
} 

और निम्नलिखित registation:

तो निम्नलिखित इंटरफेस पर विचार

var builder = new ContainerBuilder(); 

builder.RegisterSource(new ContravariantRegistrationSource()); 

builder.RegisterType<ObjectToStringConverter>() 
    .As<IConverter<object, string>>(); 

var container = builder.Build(); 

इस डिजाइन और विन्यास के साथ, मैं था ऐसा करने में सक्षम होने की उम्मीद है:

// This call succeeds because IConverter<object, string> is 
// explicitly registered. 
container.Resolve<IConverter<object, string>>(); 

// This call fails, although IConverter<string, object> is 
// assignable from IConverter<object, string>. 
container.Resolve<IConverter<string, object>>(); 

या मुझे इसे और अधिक संक्षेप में डाल दिया, यह देखते हुए परिभाषा के साथ करते हैं: निम्नलिखित कॉल सफल होने के लिए

builder.RegisterType<AToCConverter>() 
    .As<IConverter<C, A>>(); 

मैं उम्मीद करेंगे:

public class A { } 
public class B : A { } 
public class C : B { } 

public class AToCConverter : IConverter<A, C> { ... } 

और निम्नलिखित पंजीकरण

container.Resolve<IConverter<C, A>>(); 
container.Resolve<IConverter<B, B>>(); 
container.Resolve<IConverter<A, C>>(); 

हम ऑटोफैक के साथ ऐसा कैसे कर सकते हैं?

उत्तर

4

मुझे लगता है कि यह एक ऐसी सीमा है जिसे हम ऑटोफैक में पार करने की संभावना नहीं रखते हैं, लेकिन यह अन्वेषण करना दिलचस्प है।

हम contravariant 'संकल्प' कर सकते हैं क्योंकि एक सामान्य प्रकार तर्क दिया जाता है हम सभी आधार/इंटरफ़ेस प्रकारों को प्राप्त कर सकते हैं जिन पर यह तर्क असाइन किया जा सकता है। यही कारण है, दिया जाता है string हम object के लिए कार्यान्वयन के लिए खोज सकते हैं, IComparable आदि

विपरीत दिशा में जा रहे हैं - एक तर्क प्रकार से अपने उपवर्गों के सभी के लिए - इतना आसान नहीं है। object को देखते हुए हमें बाकी सब कुछ देखने के लिए कुछ रास्ता चाहिए।

कंटेनर में पंजीकृत ठोस घटकों के ज्ञान का उपयोग करना संभव हो सकता है, उदा। संभावित कार्यान्वयन की तलाश में सभी घटकों को स्कैन करें और पीछे की ओर काम करें, लेकिन यह ऑटोफैक के लिए बहुत अच्छा नहीं है क्योंकि हम कई मामलों में घटकों को आलसी बनाने के लिए 'पुल' मॉडल पर भरोसा करते हैं।

आशा है कि यह विचार के लिए भोजन है, यह देखने में रुचि है कि आप क्या कर रहे हैं।

1

आप यह देखकर सही हैं कि ContravariantRegistrationSource केवल एक सामान्य पैरामीटर वाले प्रकारों को पहचानता है। the source पर देख रहे हैं (वर्तमान में लगभग 166 लाइन पर) आप उस सीमा को वहां देखेंगे। संभावित उम्मीदवारों को प्रदान करने के लिए पंजीकरण स्रोत की आवश्यकता है, यह देखते हुए कि मैं समझ सकता हूं कि सीमा को उठाने के लिए कार्यान्वयन में अधिक जटिलता की आवश्यकता होगी।

मैं कहूंगा कि यह साबित नहीं करता है कि आप ऑटोफैक की सीमा तक पहुंच चुके हैं, केवल इस विशेष पंजीकरण स्रोत की सीमाएं हैं। मैं इसे ContravariantRegistrationSource कार्यान्वयन को बढ़ाने के लिए पाठक के लिए एक अभ्यास के रूप में छोड़ दूंगा और मुझे यकीन है कि ऑटोफैक प्रोजेक्ट कोर में इसे स्वीकार करने के लिए खुश है।

+0

1 के साथ समानता की जांच contravariant पैरामीटर की संख्या गिनती है; अन्य (गैर-contravariant) पैरामीटर की मनमानी संख्या अभी भी संभाला जा सकता है। चीयर्स! –

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