2010-03-02 7 views
41

क्या हैं गतिशील कार्यावधि में कोड पैदा करने के लिए CodeDOM बनाम Reflection.Emit पुस्तकालय को उपयोग करने के पेशेवरों/विपक्ष?Reflection.Emit बनाम CodeDOM

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

मुझे यकीन है कि मैं उपयुक्त तकनीक का चयन करने से पहले मैं कार्यान्वयन में बहुत गहरा प्राप्त करना चाहते हैं। इन अलग-अलग कोड-जनरेशन तकनीकों के भिन्न होने के बारे में कोई जानकारी उपयोगी होगी। साथ ही, ओपन-सोर्स लाइब्रेरीज़ पर कोई भी जानकारी जो या तो एपीआई या तो काम को सरल या व्यवस्थित करती है, भी उपयोगी होगी।

+1

इसे पढ़ने में, एनएचबर्ननेट मेरे सिर में पॉप करने वाली पहली बात थी। क्या यह देखने लायक होगा कि वे यह कैसे करते हैं? – quip

+1

मैं वास्तव में इसे देख रहा हूं। वे प्रतिबिंब का उपयोग करते हैं। स्वीकार करें, लेकिन यह स्पष्ट नहीं है कि उन्होंने कोड बनाम कोडम क्यों चुना। – LBushkin

उत्तर

50

मुझे लगता है कि CodeDOM और Reflection.Emit के बारे में प्रमुख बिंदु इस प्रकार हैं:

  • CodeDom सी # स्रोत कोड उत्पन्न करता है और आम तौर पर एक समाधान का हिस्सा के रूप में शामिल है और में संकलित की जब कोड जनरेट प्रयोग किया जाता है आईडीई (उदाहरण के लिए, LINQ से SQL कक्षाएं, डब्ल्यूएसडीएल, एक्सएसडी सभी इस तरह से काम करते हैं)। इस परिदृश्य में आप जेनरेट कोड को कस्टमाइज़ करने के लिए आंशिक कक्षाओं का भी उपयोग कर सकते हैं। यह कम कुशल है, क्योंकि यह सी # स्रोत उत्पन्न करता है और फिर संकलक को इसे पार्स करने के लिए चलाता है (फिर से!) और इसे संकलित करें। आप अपेक्षाकृत उच्च स्तरीय संरचनाओं का उपयोग करके कोड उत्पन्न कर सकते हैं (सी # अभिव्यक्ति & कथन के समान) जैसे लूप।

  • प्रतिबिंब। एक आईएल उत्पन्न करता है ताकि यह सीधे एक असेंबली उत्पन्न करता है जिसे केवल स्मृति में ही संग्रहीत किया जा सकता है। एक परिणाम के एक बहुत अधिक efficient.You निम्न स्तर के आईएल कोड उत्पन्न करने के लिए है के रूप में (मान स्टैक पर जमा हो जाती है; पाशन छलांग का उपयोग कर लागू किया जाना है), इसलिए पैदा करने के लिए किसी भी और अधिक जटिल तर्क थोड़ा मुश्किल है।

सामान्य तौर पर, मुझे लगता है कि Reflection.Emit आमतौर पर पसंदीदा तरीका कार्यावधि में कोड जनरेट करने के रूप में माना जाता है, जबकि जब से पहले कोड जनरेट संकलन समय CodeDOM पसंद किया जाता है। आपके परिदृश्य में, उनमें से दोनों शायद ठीक काम करेंगे (हालांकि कोडडॉम को उच्च-विशेषाधिकारों की आवश्यकता हो सकती है, क्योंकि इसे वास्तव में सी # कंपाइलर का आह्वान करने की आवश्यकता है, जो किसी भी .NET स्थापना का हिस्सा है)।

एक अन्य विकल्प Expression class उपयोग करने के लिए किया जाएगा। .NET 4.0 में यह आपको सी # अभिव्यक्तियों और बयानों के बराबर कोड उत्पन्न करने की अनुमति देता है। हालांकि, यह आपको कक्षाएं उत्पन्न करने की अनुमति नहीं देता है। तो, आप Reflection.Emit के साथ इस गठबंधन करने के लिए (कक्षा प्रतिनिधि है कि कार्यान्वयन Expression का उपयोग कर तैयार किए गए कोड उत्पन्न करने के लिए) कर सकता है। कुछ परिदृश्यों के लिए आपको वास्तव में पूर्ण श्रेणी पदानुक्रम की आवश्यकता नहीं हो सकती है - अक्सर Dictionary<string, Action> जैसे गतिशील रूप से जेनरेट किए गए प्रतिनिधियों का एक शब्दकोश पर्याप्त हो सकता है (लेकिन बेशक, यह आपके सटीक परिदृश्य पर निर्भर करता है)।

+0

यह मेरी समझ है कि कोडडॉम भी [स्मृति में कोड उत्पन्न कर सकता है] (http://msdn.microsoft.com/en-us/library/system.codedom.compiler.compilerparameters.generateinmemory.aspx)? –

+0

क्या आप विस्तृत कर सकते हैं कि आप CodeDom के साथ आंशिक कक्षाओं का उपयोग कैसे कर सकते हैं? यदि मेरा शोध कुछ भी इंगित करता है, तो यह है कि आप 'आंशिक' का उपयोग नहीं कर सकते हैं: यह 'TypeAttributes' enum में भी एक विकल्प नहीं है। –

+0

एक पूरा उत्तर। धन्यवाद। – nawfal

6

आप ExpandoObject को देखने के लिए चाहते हो सकता है। हालांकि यह केवल .NET 4.0 है।

14

कोडडॉम को लक्षित करने वाला कोड बनाए रखने में आसान होता है, क्योंकि आप सी # कोड उत्पन्न कर रहे हैं और आईएल नहीं (अधिक लोग आईएल से सी # पढ़ सकते हैं)। फ़्यूथरमोर, अगर आपको अपना कोडडॉम कोड गलत लगता है, तो आपको एक कंपाइलर त्रुटि मिलती है; यदि आप अवैध आईएल उत्पन्न करते हैं, तो आपको घातक अपवाद या क्रैश मिलता है।

हालांकि, क्योंकि कोडडॉम csc.exe कंपाइलर को आमंत्रित करता है, यह उपयोग के लिए कोड तैयार करने के लिए थोड़ा धीमा है। प्रतिबिंब के साथ। स्वीकार करें, आप सीधे स्मृति में कोड उत्पन्न कर सकते हैं।

कोडडॉम शायद अधिकांश चीजों के लिए ठीक है; XmlSerializer और WinForms डिजाइनर इसका उपयोग करते हैं।

+0

XmlSerializer कोडडॉम का उपयोग करने के लिए क्या करता है? क्षमा करें, मैं इसे परावर्तक में देख सकता हूं लेकिन मैं आलसी हूं क्योंकि मेरा ध्यान कई अन्य मुद्दों के बीच बांटा गया है और चूंकि आपने इसके बारे में उत्तर दिया है, मुझे लगता है कि आप पहले ही निवेश कर चुके हैं ताकि आप इस पर बहुत अधिक समय व्यतीत किए बिना उत्तर टाइप कर सकें या तो। –

+0

@ WaterCoolerv2 अगर मुझे लगता है कि वे लक्ष्य प्रकारों को पढ़ने/लिखने के लिए एक असेंबली बनाते हैं। मुझे एक बार एक राक्षसी, प्रतिबिंब-आधारित डेटा एक्सेस परत के साथ एक परियोजना में लाया गया था। यह कुत्ता धीमा था, इसलिए उपयोगकर्ताओं ने इसे नफरत की, लेकिन कोई भी इसे ठीक करने के बारे में नहीं जानता था। मैंने इसे कैशिंग और एमिट के संयोजन के साथ व्यावहारिक रूप से तात्कालिक बना दिया। तस्वीर के धीमे प्रतिबिंब को काटने के अलावा, आप क्रमशः प्रक्रियाओं के दौरान विशिष्ट प्रतिनिधियों को ब्रांच करने या कॉल करने के बजाय, पहले प्रकारों का निरीक्षण करके और उपयुक्त ओपोड को सीधे विधि में उत्सर्जित करके ओवरहेड को भी हटा सकते हैं। – Daniel

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