2013-06-18 25 views
8

का उपयोग कर डीएलएल में ओवरराइडिंग विधि मुझे यह भी सुनिश्चित नहीं है कि यह संभव है तो माफ़ी नहीं है। मैंने काफी बड़े पैमाने पर गुमराह किया है और जो भी मैं ढूंढ रहा हूं उसे नहीं मिला।प्रतिबिंब

असल में हमारे पास एक तीसरे पक्ष द्वारा उत्पादित एक आवेदन है, जो पूरी तरह से बदमाश होने के लिए बकवास है। हमारे पास एक विशेष समस्या है और डीएलएल के भीतर एक विधि में ILSpy का उपयोग कर समस्या का पता लगाने में कामयाब रहा है। स्पष्ट रूप से हमारे पास स्रोत कोड नहीं है (न ही प्राप्त करने में सक्षम हैं) और कंपनी किसी भी उचित समय-समय पर समस्या को ठीक करने के लिए तैयार नहीं है।

तो, हमने जांच के विभिन्न मार्गों की जांच की है और कुछ भी नहीं आया है। मैं यह देखने में देख रहा हूं कि यह प्रतिबिंब का उपयोग करके किया जा सकता है और यह आखिरी उम्मीद है कि हमें यह काम करने के लिए मिल रहा है।

  • मौजूदा DLL के रूप में एक ही नाम के साथ एक सरल वर्ग पुस्तकालय बनाएं
  • उपयोग प्रतिबिंब
  • किसी तरह मौजूदा DLL से तरीकों आयात करने के लिए: संक्षेप में, मुझे क्या करना चाहते हैं निम्नलिखित है अपने स्वयं के साथ प्रश्न में विधि को ओवरराइड करें, सही कोड
  • कोड को पुनर्निर्माण करें, इसलिए मेरे पास एक नया डीएलएल है, जिसमें मौजूदा डीएलएल की 99% कार्यक्षमता है लेकिन मेरे ओवरराइड कोड सही कार्यक्षमता प्रदान करते हैं।

मैंने पाया है कि, मेरी जांच के दौरान TypeBuilder.DefineMethodOverride और StackOverflow से एक पृष्ठ भी मिलता है, जो समान लगता है लेकिन काफी कुछ नहीं जो मैं ढूंढ रहा हूं।

http://msdn.microsoft.com/en-us/library/system.reflection.emit.typebuilder.definemethodoverride.aspx

Is there a way to "override" a method with reflection?

किसी भी सलाह की सराहना की!

एंड्रयू

संपादित

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

+0

आश्चर्य है कि एक इंटरसेप्टर आधारित दृष्टिकोण यहां काम करेगा - कैसल डायनैमिकप्रॉक्सी जैसे कुछ: http://www.castleproject.org/projects/dynamicproxy/ - जाहिर है कि आप पूरी तरह से विधि कॉल को प्रतिस्थापित नहीं करेंगे, लेकिन आप निश्चित रूप से अवरोध कर सकते हैं/त्रुटि संभाल और tweak (ओह हाँ और यह निर्भर करता है कि कक्षा में आभासी तरीकों हैं) – Charleh

+0

क्यों न केवल एक कक्षा बनाओ, जैसा कि आपने कहा था, जो उस विधि को छोड़कर अधिकांश चीजों के लिए तीसरे पक्ष की कक्षा को कॉल करता है जिसे आप ओवरराइड करना चाहते हैं? या उस वर्ग से निकला है और उस विधि के लिए एक और नाम का उपयोग करें? क्या आपको वास्तव में 1 अद्वितीय डीएल के अंदर रहने की ज़रूरत है? इसे 2 में विभाजित क्यों नहीं करें? – ppetrov

उत्तर

6

आप केवल वर्चुअल होने पर विधि को ओवरराइड कर सकते हैं, और इससे कोई फर्क नहीं पड़ता कि आप इसे प्रतिबिंब या स्थैतिक रूप से करते हैं या नहीं। मैं एक डीकंपलर का उपयोग करने का सुझाव दूंगा (वहां बहुत सारे मुफ्त उपलब्ध हैं) और एमएसआईएल में कोड को ठीक करना। फिर आप एमएसआईएल से एक नई असेंबली उत्पन्न कर सकते हैं।

+0

हाँ, मैंने अभी जांच की है और विधि वर्चुअल नहीं है, इसलिए खिड़की से एक विचार है। मैं अभी डिकंपेलर की जांच कर रहा हूं - आपकी सलाह के लिए धन्यवाद। – Andrew

+0

साइन और प्रकाशन के बारे में कैसे? क्या यह वही रहता है? –

+0

यदि डीएलएल हस्ताक्षरित है (इसका एक मजबूत नाम है) तो संशोधन के बाद आपको इसे मजबूत नाम के प्रमाणपत्र से इस्तीफा देना होगा। –

0

मुझे लगता है कि आपका पहला विचार अच्छा है। यदि तृतीय पक्ष वर्ग sealed नहीं है, तो आप इससे प्राप्त कर सकते हैं, और गलत व्यवहार को सही करने के लिए, एक अलग नाम के साथ अपनी खुद की विधि जोड़ सकते हैं। यदि आपको इसे 1 डीएल में होने की आवश्यकता है, तो आप IlMerge का उपयोग कर सकते हैं।

यदि आपकी तीसरी पार्टी कक्षा सील कर दी गई है तो आप अपनी नई कक्षा में इस तीसरे पक्ष की कक्षा का उदाहरण दे सकते हैं और आवश्यकता होने पर विधियों को कॉल कर सकते हैं।

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

यह बहुत साफ नहीं है, लेकिन पुस्तकालय को संपादित करने वाली कंपनी समस्या को हल करने के दौरान यह एक अस्थायी समाधान हो सकता है।

और जब यह तय हो जाए तो आपको केवल उस विधि का नाम बदलना होगा जिसका उपयोग आप करते हैं, इसलिए यह समय लेने वाला नहीं होगा।

0

जो आपने वर्णन किया है उससे मैं मूल असेंबली को संशोधित करने की अनुशंसा करता हूं। प्रक्रिया MSIL, सी # या जो कुछ भी भाषा में विधानसभा डिकंपाइल अनिवार्य रूप से

  • है तुम इतनी
  • decompiled विधानसभा संशोधित अपने परिवर्तनों
  • पुनः संकलित विधानसभा संशोधित स्रोत

का उपयोग कर शामिल करने का निर्णय मैं देख सकता हूं कि Reflexil आपको ऐसा करने की अनुमति देता है, हालांकि इसके लिए आपको Resharper (मैंने इसे स्वयं नहीं किया है) खरीदने की आवश्यकता हो सकती है

वैकल्पिक रूप से आप ILDasm उपयोग कर सकते हैं एक एकल फाइल करने के लिए पूरे विधानसभा डिकंपाइल करने के लिए, फ़ाइल को संशोधित और उसके बाद का उपयोग कर इसे पुन: संयोजित ILAsm

0

मैं जानता हूँ कि मैं इस पर देर से कुछ देर में आ रहा हूँ, लेकिन मैं Charleh से सहमत चाहते हैं; अगर आपके पास ऐसी कक्षा है जो अच्छी तरह से व्यवहार नहीं कर रही है और प्रतिस्थापन के लिए अनुकूल नहीं है, लेकिन कम से कम virtual के रूप में अपनी विधियों की घोषणा करता है, तो आप भाग्यशाली हैं। निम्नलिखित Castle.Core और Patterns के लिए संदर्भ का उपयोग करता है:

var interceptor = new DelegateInterceptor(proceed: call => 
{ 
    if(ShouldCallProceed(call)) call.Proceed(); 
    else AlternativeLogic(); 
}); 

var generator = new ProxyGenerator(); 
var proxy = generator.CreateClassProxy<UncooperativeType>(interceptor); 

proxy.RubbishMethod(); 

मैं भी LINQPad में a running sample of this प्रदान करने की स्वतंत्रता लिया है। यह उन तरीकों के बीच अंतर दिखाता है जो अवरोध (virtual वाले) और जो नहीं करते हैं। यह Patterns से Try.Do का उपयोग कर सभी कोड के बिना अपवादों को फँसाने का एक उपयोगी तरीका भी दिखाता है।