2012-02-29 12 views
14

What's New in the .NET Framework 4.5 Developer Preview उल्लेख CustomReflectionContext वर्ग के माध्यम से डिफ़ॉल्ट प्रतिबिंब व्यवहार को ओवरराइड करने के लिए एक प्रतिबिंब संदर्भ अनुकूलित करने के लिए.NET 4.5 कस्टम रिफ्लेक्शन कॉन्टेक्स्ट: इसके लिए क्या उपयोगी है?

की क्षमता।

ReflectionContext का उद्देश्य क्या है? एमएसडीएन इस विषय पर बिल्कुल स्पष्ट नहीं है।

उत्तर

39

अतीत में .NET के साथ, प्रतिबिंब के माध्यम से कुछ विशेषताओं को स्वचालित करने में सक्षम होने और उन्हें अनुकूलित करने में सक्षम होने के बीच तनाव रहा है। उदाहरण के लिए, विज़ुअल स्टूडियो में प्रॉपर्टी पैनल लें - परिदृश्यों में जहां यह कुछ .NET प्रकार दिखाता है (उदा।, डिज़ाइन सतह पर नियंत्रण), यह स्वचालित रूप से टाइप की जाने वाली प्रत्येक सार्वजनिक संपत्ति को खोज और प्रदर्शित कर सकता है।

इस प्रकार के प्रकार के व्यवहार के प्रतिबिंब का उपयोग करना उपयोगी है क्योंकि इसका मतलब है कि प्रत्येक संपत्ति नियंत्रण के डेवलपर के बिना कुछ भी करने की आवश्यकता के बिना दिखाई देगी। लेकिन यह एक समस्या प्रस्तुत करता है: क्या होगा यदि आप चीजों को कस्टमाइज़ करना चाहते हैं, उदा। किसी विशेष संपत्ति के लिए वर्गीकरण या कस्टम संपादन UI परिभाषित करना?

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

एक और समस्या यह है कि कुछ स्थितियों में आप गतिशील रूप से तय कर सकते हैं कि आप 'गुण' क्या पेश करते हैं। इस के सबसे पुराने उदाहरणों में से एक (.NET 1.0 पर वापस डेटिंग) किसी प्रकार के ग्रिड नियंत्रण (या तो क्लाइंट-साइड या वेब) में DataSet डाल रहा था। दृढ़ता से टाइप किए गए डेटासेट के साथ, प्रतिबिंब यह पता लगाने के लिए एक उचित तरीका हो सकता है कि स्रोत किस गुण प्रदान करता है, लेकिन DataSet गतिशील रूप से भी उपयोग किया जा सकता है, इसलिए आपको डेटा ग्रिड को रनटाइम पर पूछने के लिए एक कॉलम की आवश्यकता है कि कौन से कॉलम प्रदर्शित हों।

(इसका एक जवाब यह है: अपने यूआई को सही ढंग से डिज़ाइन करें! इस तरह की ग्रिड उत्पन्न करना भयानक उपयोगकर्ता अनुभवों की ओर जाता है। हालांकि, बहुत से लोग इसे आलसी तरीके से करना चाहते हैं, भले ही यह एक अच्छा विचार हो या नहीं .. ।)

तो फिर आपके पास ऐसी स्थिति है जहां कभी-कभी आप प्रतिबिंब-संचालित व्यवहार चाहते हैं, लेकिन कभी-कभी आप रनटाइम पर कुल नियंत्रण लेना चाहते हैं।

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

यह डिफ़ॉल्ट रूप से रनटाइम-संचालित व्यवहार प्रदान करने के विकल्प के साथ एक समाधान प्रदान करता है यदि आप इसे चाहते हैं तो रनटाइम-संचालित व्यवहार प्रदान करने के विकल्प के साथ। लेकिन यह उस समस्या को हल नहीं करता है जहां आप केवल डिजाइन समय पर ऐसा करना चाहते हैं, और आप अपने रनटाइम पुनर्वितरण के हिस्से के रूप में उस कोड को शिप नहीं करना चाहते हैं।

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

बेशक

, कि में से कोई भी सामान्य प्रतिबिंब एपीआई के माध्यम से दिखाई है - वी.एस. और मिश्रण एक आवरण परत है कि प्रतिबिंब के शीर्ष पर बैठता है यह सब काम करने के लिए किया है।

दो वर्चुअलाइजेशन परतों कि प्रतिबिंब के माध्यम से पारित कर सकते हैं, या संवर्धित कर सकते क्या प्रतिबिंब से बाहर आता है तो अब हम मिल गया है ...

यह .NET 4.5 में की तरह दिखता है, CLR टीम ने निर्णय लिया कि जब से विभिन्न समूह पहले से ही बात की इस तरह कर रहे थे, और अन्य समूहों इसके बारे में और अधिक करना चाहता था, वास्तव में यह बात की तरह है कि होना चाहिए था (MEF टीम के लिए प्रतिबिंब संचालित-साथ-वैकल्पिक-क्रम-वृद्धि व्यवहार समान आवश्यकताओं था) रनटाइम में बनाया गया।

नया मॉडल ऐसा प्रतीत होता है: ReflectionContext बेस क्लास एक सार तत्व है जिसके माध्यम से आप प्रतिबिंब API का आभासी संस्करण प्राप्त कर सकते हैं। प्रतिबिंब अब बॉक्स से बाहर virtualizable है - क्योंकि मुख्य विचारों में से एक है कि आप अब प्रकार वर्णनकर्ता सिस्टम की तरह विशेष एपीआई की जरूरत है अपने एकमात्र गोल प्रतिबिंब के शीर्ष पर एक virtualizable आवरण पाने के लिए है अगर है यह भ्रामक आसान है। तो तुम बात इस तरह की

public static void ShowAllAttributes(Type t) 
{ 
    foreach (Attribute attr in t.GetCustomAttributes(true)) 
    { 
     Console.WriteLine(attr); 
    } 
} 

अब तुम हमेशा कि लिखने के लिए कर लिया है लिख सकते हैं, लेकिन .NET 4.5 करने से पहले, इस तरह कोड हमेशा 'असली' प्रकार की जानकारी के खिलाफ काम कर जाएगा, क्योंकि यह प्रतिबिंब का उपयोग करता है । लेकिन प्रतिबिंब संदर्भों के लिए धन्यवाद, अब वर्चुअलाइज्ड Type के साथ इसे प्रदान करना संभव है। तो यह बहुत उबाऊ प्रकार पर विचार करें:

class NoRealAttributes 
{ 
} 

आप बस अपना ShowAllAttributes विधि के लिए typeof(NoRealAttributes) पार कर लेते हैं, यह कुछ भी बाहर प्रिंट होगा।

class MyReflectionContext : CustomReflectionContext 
{ 
    protected override IEnumerable<object> GetCustomAttributes(MemberInfo member, IEnumerable<object> declaredAttributes) 
    { 
     if (member == typeof(NoRealAttributes)) 
     { 
      return new[] { new DefaultMemberAttribute("Foo") }; 
     } 
     else 
     { 
      return base.GetCustomAttributes(member, declaredAttributes); 
     } 
    } 
} 

(वैसे, मुझे लगता है कि CustomReflectionContext और उसके आधार के बीच भेद, ReflectionContext कि बाद एक virtualizable प्रतिबिंब संदर्भ के लिए एपीआई को परिभाषित करता है, जबकि: लेकिन मैं एक (कुछ काल्पनिक) कस्टम प्रतिबिंब संदर्भ में लिख सकते हैं CustomReflectionContext यह आसान आप ऐसी बात को लागू करने के लिए बनाने के लिए कुछ सहायकों कहते हैं) और अब मुझे लगता है कि का उपयोग अपने वर्ग के लिए Type के एक आभासी संस्करण प्रदान करने के लिए कर सकते हैं:।

var ctx = new MyReflectionContext(); 
Type mapped = ctx.MapType(typeof(NoRealAttributes).GetTypeInfo()); 
ShowAllAttributes(mapped); 

इस कोड में, mapped अभी भी को संदर्भित करता है Type ऑब्जेक्ट , इसलिए कुछ भी जो प्रतिबिंब एपीआई का उपयोग करने के बारे में जानता है, उसके साथ काम करने में सक्षम होगा, लेकिन अब यह उस विशेषता की उपस्थिति की रिपोर्ट करेगा जो वास्तव में वहां नहीं है। बेशक, Type सार है, इसलिए हम हमेशा कुछ है कि कि से ली गई है, और अगर आप फोन mapped.GetType() आप देखेंगे कि यह वास्तव में एक System.Reflection.Context.Custom.CustomType बजाय System.RuntimeType आप सामान्य रूप से देखना चाहते हैं है। और वह CustomType वस्तु अपने कस्टम संदर्भ के अंतर्गत आता है, इसलिए किसी भी अन्य प्रतिबिंब एपीआई वस्तुओं आप उसके बीच की पकड़ पाने के (जैसे, यदि आप mapped.Assembly.GetTypes() लिखा था) आप भी अनुकूलित वस्तुओं है कि अपने कस्टम संदर्भ के माध्यम से जाना है, जो का अवसर होगा मिल चाहते हैं बाहर आने वाली किसी और चीज को संशोधित करें।

तो कोड अनुकूलित Type वस्तु का उपयोग कर प्रकार प्रणाली के माध्यम से नेविगेट कर सकते हैं।भले ही ऐसा कोड साधारण मूल प्रतिबिंब एपीआई का उपयोग कर रहा है, लेकिन अब मुझे फिट होने पर कुछ भी अनुकूलित करने का अवसर है।

यदि आप इसके लिए पूछते हैं तो आपको केवल यह आभासी दृश्य मिलता है। उदाहरण के लिए, .NET 4.5 में एमईएफ एक कस्टम विशेषता के लिए दिखता है जो निर्दिष्ट करता है कि इसे उपयोगकर्ता द्वारा प्रदान किए गए कस्टम प्रतिबिंब संदर्भ का उपयोग करना चाहिए, लेकिन अन्यथा सामान्य प्रतिबिंब में वापस आ जाएगा। (और मेरे ShowAllAttributes विधि के मामले में, इसे इस्तेमाल करता है जो कुछ भी Type वस्तु मैं पारित करने के लिए चुनते हैं -। अगर यह एक आभासी या एक 'असली' प्रकार वस्तु हो रही है यह पता नहीं है)

संक्षेप में

तो, यह साधन यदि आप वर्चुअलाइज्ड प्रकार की जानकारी चाहते हैं तो आपको प्रतिबिंब एपीआई के आसपास विज्ञापन हॉक रैपर की आवश्यकता नहीं है।

+0

यह एक अच्छा जवाब है, बहुत बहुत धन्यवाद। मुझे उम्मीद है कि वे किसी भी मौजूदा प्रतिबिंब कॉल को वर्चुअलाइज करने की अनुमति देंगे (जो मौजूदा एमएस और गैर-एमएस पुस्तकालयों में बहुत सी अनावश्यक प्रतिबिंब-आधारित सीमाओं में मदद करेगा)। तो यह सिर्फ एक अंतर्निहित सहायक है जो हम पहले से कर सकते हैं। खैर, यह भी उपयोगी साबित हो सकता है। –

+0

मैं संभवतः कितने अंक प्रदान कर सकता हूं? एक बात के लिए, आपने मुझे यह नोटिस करने के लिए प्रेरित किया कि मैं जिस अस्पष्ट चीज को पार करता हूं (रिफ्लेक्टर ट्रैवलिंग के माध्यम से) वास्तव में 4.5 पर नया है और उन छोड़े गए इंटरऑप क्लंकरों में से एक नहीं है। .NET में बहुत से लोग हैं (आप कुछ उल्लेख करते हैं)। बोनांजा! अगर मैं किसी संपत्ति को ऑन-द-फ्लाई (जैसा कि डॉक्टर में वादा किया गया है) पर वर्चुअल बना सकता है और उन्हें वीएस इंटेलिजेंस में दिखाई देता है, तो मैं खुशी से रोना चाहता हूं। 1,001 विफल प्रयासों पर बर्बाद होने पर हर बार कभी न सोचें (नवीनतम और शायद सबसे खराब 'सिस्टम टाइप' नक्षत्र को पूरी तरह से उपclass करने की कोशिश कर रहा था)। कोशिश करने के लिए वू-हू बंद ... –

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