2009-01-06 15 views
5

अजीब व्यवहार का उपयोग कर विधानसभाओं की लोडिंग मिश्रण जब Assembly.LoadFrom और Assembly.Loadअजीब व्यवहार जब Assembly.LoadFrom और Assembly.Load

का उपयोग कर विधानसभाओं की लोडिंग मिश्रण मैं जब Assembly.LoadFrom साथ विधानसभाओं लोड हो रहा है एक अजीब व्यवहार का सामना करना पड़ा और बाद में विधानसभा के साथ। लोड।
मैं असेंबली.लोड लोड का उपयोग कर एक असेंबली लोड कर रहा हूं, जहां असेंबली किसी फ़ोल्डर में स्थित है जो निष्पादन फ़ोल्डर नहीं है।

बाद में मेरे टेस्ट कोड में जब मैं असेंबली के साथ इस असेंबली को फिर से लोड करने का प्रयास करता हूं। लोड, लोड एक System.IO.FileNotFoundException ("फ़ाइल या असेंबली लोड नहीं कर सका ...") के बावजूद विफल रहता है असेंबली पहले ही लोड हो चुकी है। लोड मजबूत नाम और गैर-मजबूत नाम दोनों के साथ विफल रहता है (एक बार फिर से लोड करने के लिए मूल कारण यह असेंबली बाइनरीफॉर्मेटर का उपयोग है)।

हालांकि, यदि असेंबली निष्पादन फ़ोल्डर में स्थित है, तो बाद में लोड मजबूत नाम और मजबूत नाम के साथ दोनों मामलों में सफल हो जाता है। इस मामले में आप देख सकते हैं कि दो समान असेंबली दो अलग-अलग स्थानों से लोड की जाती हैं।

एक साधारण कोड का नमूना है कि इस समस्या का पुनर्निर्माण करने वाला -

विधानसभा assembly1 = Assembly.LoadFrom (@ "C: \ a.dll");

// एक मजबूत नाम के साथ लोड हो रहा है विफल रहता है विधानसभा assembly2 = Assembly.Load (@ "एक, संस्करण = 1.0.0.0, संस्कृति = तटस्थ, PublicKeyToken = 14986c3f172d1c2c");

// गैर-मजबूत विफलताओं के साथ लोडिंग विधानसभा विधानसभा 3 = विधानसभा.लोड (@ "ए");

  1. कोई स्पष्टीकरण क्यों सीएलआर पहले से लोड की गई असेंबली को अनदेखा करता है?
  2. कोई विचार मैं इस समस्या को कैसे कम कर सकता हूं?

धन्यवाद।

उत्तर

9

यह अजीब नहीं है। प्रलेखन के अनुसार, लोड और लोडफ्रॉम के साथ लोडिंग असेंबली को विभिन्न संदर्भों में रखेगी। This मदद कर सकता है।

  1. कोई स्पष्टीकरण क्यों CLR पहले से ही भरी हुई विधानसभा पर ध्यान नहीं देता?

क्योंकि वे एक अलग संदर्भ में हैं।

  1. कोई विचार मैं इस समस्या को कैसे कम कर सकता हूं?

उसी संदर्भ से लोड करें, या मदद CLR विधानसभा मिल जाए, शायद AppDomain.AssemblyResolve करने के लिए एक हैंडलर संलग्न करके।

वैकल्पिक

तो स्थान आप से विधानसभाओं लोड कर रहे हैं AppDomain के तहत एक सबफ़ोल्डर है।BaseDirectory आप बस अपने App.config लिए एक प्रवेश जोड़ सकते हैं:

<configuration> 
    <runtime> 
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
     <probing privatePath="bin;bin2\subbin;bin3"/> 
     </assemblyBinding> 
    </runtime> 
</configuration> 

http://msdn.microsoft.com/en-us/library/823z9h8w.aspx

7

@Kent Boogart: सही व्याख्या हो गया लगता है यही कारण है कि। पूरी जानकारी के लिए, सुजान कुक इस ब्लॉग पोस्ट जो मूल एक तुम्हें तैनात की तुलना में थोड़ा अधिक बताते हैं: http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx

के बाद कोड का लाभ है AppDomain.AssemblyResolve -

// register to listen to all assembly resolving attempts: 
AppDomain currentDomain = AppDomain.CurrentDomain; 
currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler); 


// Check whether the desired assembly is already loaded 
private static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args) { 
    Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); 
    foreach (Assembly assembly in assemblies) { 
     AssemblyName assemblyName = assembly.GetName(); 
     string desiredAssmebly = args.Name; 
     if (assemblyName.FullName == desiredAssmebly) { 
      return assembly; 
     } 
    } 

    // Failed to find the desired assembly 
    return null; 
} 
संबंधित मुद्दे