2009-07-27 13 views
6

मैं पिछले कुछ हफ्तों में इसे क्रैक करने की कोशिश कर रहा हूं और अभी तक कोई अच्छा समाधान नहीं मिला है; उम्मीद है कि मैं यहां एक जवाब प्राप्त कर सकता हूं।रनटाइम पर असेंबली के 2 संस्करण लोड हो रहा है

मेरे पास दो असेंबली (ZA & जेडबी) हैं, जिनमें से दोनों एक आम परियोजना/डीएलएल (जेडसी) को इंगित करते हैं, लेकिन जो एक अलग संस्करण (यानी एक ही डीएलएल नाम, समान नामस्थान, कुछ कक्षाएं अलग हो सकती हैं) पर हो सकती हैं। । प्रत्येक असेंबली स्वयं ही काम करती है, हालांकि, अगर किसी को रनटाइम पर लोड किया जाता है (उदा। ए लोड बी), तो मैं इसे काम नहीं कर सकता। कुछ मदद की जरूरत है।

यहाँ सेटअप है:

  • ZA ZC पर निर्भर करता है (सामान्य) संस्करण 1.1
  • ZB ZC संस्करण पर निर्भर 1,0

ZA ZB में कुछ लोड करने के लिए की जरूरत है लोड करने के लिए की जरूरत है (जो रनटाइम पर, जेडसी पर निर्भर करता है)।

जेडए मास्टर ऐप है। इसकी bin निर्देशिका के तहत, एक प्लगइन्स निर्देशिका plugins/plugin-ZB है जिसके अंतर्गत मैं सभी जेडबी और इसकी निर्भरता (जेडसी) रखना चाहता हूं। ठीक काम -

Assembly.Load() dll का एक ही संस्करण का उपयोग कर:

यहाँ मैं अब तक की कोशिश की है है।

Assembly.Load() डीएल के विभिन्न संस्करणों का उपयोग करके - जेडबी लोड, लेकिन जब विधि चलती है, तो मुझे एक विधि अपवाद नहीं मिला है।

AppDomain.Load() को फ़ाइल मिली नहीं मिली; मैंने असेंबली को हल करने के लिए प्रतिनिधि का भी इस्तेमाल किया।

जेडसी: के बारे में कुछ विवरण - कुछ विधियां सार्वजनिक स्थिर हैं (कुछ नहीं हैं)। जैसे Log.Log("hello"); - कुछ मूल्य (प्राइमेटिव्स या ऑब्जेक्ट्स) वापस कर सकते हैं। - कुछ विधियां गैर स्थैतिक (और मूल्य मान) हैं।

सहायता? - टीआईए

उत्तर

1

जोनाथन एलन उत्कृष्ट सलाह के अलावा, समस्या को हल करने के लिए एक और "शास्त्रीय" तरीका 2 अलग-अलग AppDomanis में 2 संस्करण लोड करके है। फिर आप दो AppDomains कम्यूनिक बनाने के लिए .NET Remoting का उपयोग कर सकते हैं। इसलिए जेडए को एक नया एपडोमेन बनाना चाहिए, इस ऐपडोमेन जेडबी में लोड करें और रीमोटिंग के माध्यम से जेडबी में कुछ ऑपरेशन का आह्वान करें।

ध्यान दें कि .NET Remoting के उन वर्गों पर कुछ आवश्यकताएं हैं जिन्हें आप उपयोग करना चाहते हैं (मार्शलबीरफ से विरासत), और एक ऐपडॉमेन बनाना एक महंगा ऑपरेशन है।

आशा इस मदद

+0

"आप केवल एक AppDomain के लिए एक विधानसभा का एक संस्करण हो सकता है" सच नहीं है। एक असेंबली से असेंबली के दो संस्करणों को संदर्भित करना भी संभव है, अधिक जानकारी के लिए बाहरी उपनाम देखें, यह पहली बात है जो फीचर के उदाहरण के साथ Google पर पॉप अप करती है: http://blogs.msdn.com/ बी/ansonh/संग्रह/2006/09/28/extern-alias-walkthrough.aspx – Graham

+0

दो ऐपडोमेन का उपयोग करना समस्या का समाधान है हालांकि। – Graham

+0

आप सही, अद्यतन का जवाब दिया! –

0

मैं एक ही विधानसभा एक ही समय में लोड के दो संस्करणों पड़ा है। यह एक परिदृश्य के साथ हुआ जैसा आपने वर्णन किया था।

आपको जेडए और जेडबी दोनों के लिए जेडसी के समान संस्करण को लोड करने के लिए रनटाइम को मनाने के लिए है।

  1. अपने App.config फ़ाइल में एक bindingRedirect तत्वों का उपयोग करें: मैं दो तरीकों से ऐसा करने के लिए मिल गया है। this question में कुछ विवरण हैं।
  2. AppDomain.AssemblyResolve ईवेंट का उपयोग करें। this answer में कुछ विवरण हैं।

AppDomain.AssemblyResolve के साथ एकमात्र समस्या यह है कि यह केवल तब ट्रिगर होता है जब रनटाइम अनुरोधित संस्करण नहीं ढूंढ पाता है। यदि दोनों संस्करण उपलब्ध हैं, तो आपको bindingRedirect का उपयोग करना होगा। मैंने AppDomain.AssemblyResolve ईवेंट का उपयोग किया है और फिर एक सुरक्षा जांच जोड़ा है जो सुनिश्चित करता है कि असेंबली के संदर्भित असेंबली संग्रह को देखकर सही संस्करण लोड किया गया था। यदि ऐसा नहीं है, तो मैं उपयोगकर्ता से शिकायत करता हूं कि पुस्तकालय का पुराना संस्करण चारों ओर झूठ बोल रहा है और कहां है कि यह कहां है।

+1

यह दो अलग-अलग संस्करणों को लोड नहीं कर रहा है, यह एक ही संस्करण को दो बार लोड कर रहा है। –

+1

जब मुझे यह समस्या थी, @ कैमरून, जेडए शुरू होने पर रन टाइम जेडसी के संस्करण 1.1 को लोड किया गया। फिर जब मैंने ज़ेडबी प्लग लोड किया, तो रन टाइम ने जेडसी के संस्करण 1.0 को लोड किया। दो अलग-अलग संस्करणों को लोड करके मेरा यही मतलब है। जेडए और जेडबी को जेडसी से एक दूसरे तक ऑब्जेक्ट पास करने के लिए, मुझे दोनों को जेडसी के समान संस्करण को लोड करना पड़ा। यही वह है जो मैं बता रहा हूं कि मेरे जवाब में कैसे करना है। क्या मैंने मूल प्रश्न को गलत समझा है? –

3
m_Assembly1 = Reflection.Assembly.LoadFile(IO.Path.Combine(System.Environment.CurrentDirectory, "Old Version\Some.dll")) 
    m_Assembly2 = Reflection.Assembly.LoadFile(IO.Path.Combine(System.Environment.CurrentDirectory, "New Version\Some.dll")) 

    Console.WriteLine("Old Version: " & m_Assembly1.GetName.Version.ToString) 
    Console.WriteLine("New Version: " & m_Assembly2.GetName.Version.ToString) 

    m_OldObject = m_Assembly1.CreateInstance("FullClassName") 
    m_NewObject = m_Assembly2.CreateInstance("FullClassName") 

यहां से बाहर मैंने अपने परीक्षण चलाने के लिए देर से बाध्यकारी और/या प्रतिबिंब का उपयोग किया।

.NET: Load two version of the same DLL

+0

उत्कृष्ट सलाह! उसे नहीं पता था –

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