2009-07-21 15 views
10

असल में मैंने अपने समाधान के भीतर किसी प्रकार की 'स्थैतिक रूप से जुड़ी' असेंबली को लागू करने की कोशिश की।विधानसभा से पहले रनटाइम पर assemby कैसे लोड करें घटनाक्रम?

  • CopyLocal = false
  • .dll फ़ाइल स्वयं को जोड़ना 'कड़ी के रूप में जोड़ें' के साथ अपने समाधान के लिए .dll फ़ाइल स्वयं को जोड़ने के साथ अपने विधानसभा के लिए एक संदर्भ जोड़ना: तो मैं निम्नलिखित की कोशिश की के साथ अपने संसाधनों 'जोड़ें संसाधन' -
  • रूप private MyObject temp = new MyObject();

इन चरणों का मैं FileNotFoundException मिला अपेक्षा के अनुरूप करने के बाद Form1 में मेरी विधानसभा से बाहर कुछ प्रकार जोड़ा जा रहा है 'मौजूदा फ़ाइल जोड़ें'। तो चलो इस त्वरित हैक

AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => 
    { 
     Assembly MyAssembly = AppDomain.CurrentDomain.Load(Properties.Resources.ExternalAssembly); 
     return MyAssembly; 
    }; 

तो यह काम करता है के साथ AssemblyResolveEvent भीतर विधानसभा लोड करने का प्रयास करते हैं! मैं एक असेंबलीResolveEvent के भीतर एक संसाधन फ़ाइल से मेरी असेंबली लोड करने में सक्षम हूँ। लेकिन यह घटना केवल तभी होती है, अगर यह कहीं और मेरी असेंबली नहीं मिल पाती है। लेकिन मैं से पहले अपनी असेंबली कैसे लोड कर सकता हूं। नेट विभिन्न स्थानों को खोजने की कोशिश करता है ??

Checking for Previously Referenced Assemblies से तथ्यों के कारण मैंने सोचा कि पहले से ही डोमेन में असेंबली लोड करना संभव होगा और यह लिया जाएगा।

मैं निम्नलिखित मुख्य() विधि

static void Main() 
{ 
    LoadMyAssemblies(); 
    AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => LoadMyAssemblies(); 
    Application.EnableVisualStyles(); 
    Application.SetCompatibleTextRenderingDefault(false); 
    Application.Run(new Form1()); 
} 

private static Assembly LoadMyAssemblies() 
{ 
    Assembly result = AppDomain.CurrentDomain.Load(Properties.Resources.MyStaticAssembly); 
    return result; 
} 

का उपयोग करके Program.cs के भीतर इस की कोशिश की लेकिन यह अभी भी ResolveEventHandler में चलाता है। और कहीं भी बेहतर, अगर मैं फिर से असेंबली लोड करता हूं और ऐपडोमेन.कुरेंटडोमेन.गेटास्सेम्ब्लीज़() में देखता हूं तो मैं देख सकता हूं कि मेरी असेंबली दो बार लोड हो गई है !!

तो क्या कोई विचार है कि जब मेरी असेंबली असेंबली विधानसभा से पहले लोड हो जाती है तो उसे लोड नहीं किया जाएगा ?? डीबगर की मदद से मैं असेंबली रिसेल्व से आया था जब मैं भी एक शून्य वापस लौटा, लेकिन इस मामले में मुझे शुरुआत में एक फ़ाइलNotFoundException मिला।

उत्तर

3

बस अगर आपको पता नहीं था, तो एमएस रिसर्च से ILMerge नामक एक उपकरण है जो असेंबली को एक फ़ाइल में विलीन करता है।

इसके अलावा आप Assembly Linker tool का उपयोग करके मल्टी-फ़ाइल असेंबली बना सकते हैं।

प्लस आपके मूल प्रश्न का उत्तर देने के लिए, मुझे लगता है कि समस्या यह है कि रनटाइम यह नहीं जानता कि आपके द्वारा मैन्युअल रूप से लोड की गई असेंबली वह है जिसे वह ढूंढना चाहिए। तो विधानसभा में फिर से असेंबली लोड करने की बजाय घटना को हल करें, बस उस असेंबली के संदर्भ को वापस पास करें जिसे आपने मैन्युअल रूप से लोड किया है।

+0

आईएलएमर्ज का उपयोग पहले से ही किसी अन्य परिस्थितियों में किया जाएगा, लेकिन इस मामले के लिए यह 'सर्वश्रेष्ठ' समाधान नहीं है। असेंबली में देना एक ही असेंबली वापस लेना भी एक अच्छा समाधान नहीं है, क्योंकि यदि एक ही असेंबली प्रोग्राम फ़ोल्डर या जीएसी में भी निहित है तो यह लिया जाएगा और घटना नहीं फेंक दी जाएगी। – Oliver

3

सीएलआर बाइंडर यह नहीं जानता कि LoadMyAssemblies() असेंबली रीसोल्व घटना के समान ही काम करता है, और वे दोनों एक ही असेंबली को देखने और इसे लोड करने की कोशिश कर रहे हैं।

असेंबली रिसेल्व घटना हमेशा उस बिंदु पर निकाल दी जाती है जिस पर बाइंडर निर्णय लेता है कि उसने सभी संभावित स्थानों की खोज की है (जो उस खोज योग्य खोजकर्ता हैं) और एक मैच नहीं मिला।

यह मूल प्रश्न पूछता है, यानी, आप अपने प्रबंधित असेंबली को स्थिर रूप से क्यों लिंक करना चाहते हैं?इस Static linking advantages

पर चर्चा का एक बहुत कुछ के लिए इस सूत्र पढ़ें मैं आगे जाना है और कैसे AssemblyResolve घटना 1) GAC में विधानसभा रखो से टकराने से बचने के लिए पर भाग जवाब देंगे। जहां तक ​​बाइंडर का संबंध है, जीएसी हमेशा जीतता है। 2) अपनी असेंबली को प्रोबिंग पथ में रखें और सुनिश्चित करें कि बाइंडर इसे उठाता है (इस पर अधिक जानकारी के लिए 'कैसे रनटाइम एमएसडीएन पर असेंबली ढूंढता है' देखें)।

+0

आप सही हैं, कि सीएलआर बाइंडर को मेरे फ़ंक्शन के बारे में कुछ भी पता नहीं है। लेकिन जैसा कि आपने पहले ही उल्लेख किया है, यह असेंबली रीसोल्व घटना को आग लग जाएगा जब उसने सभी संभावित स्थानों की खोज की है। लेकिन यह सच नहीं है! यह वर्तमान AppDomain के भीतर लोड असेंबली की सूची में नहीं देखा था! लेकिन इसे पढ़ने के बाद (http://msdn.microsoft.com/en-us/library/aa98tba8.aspx) इसे वहां देखना चाहिए। – Oliver

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