2009-01-21 15 views
5

मैं निम्नलिखित कोड के साथ कुछ समस्या आ रही है:Type.IsSubclassOf() AppDomains में काम नहीं करता है?

private class ClientPluginLoader : MarshalByRefObject 
{ 
    public bool IsPluginAssembly(string filename) 
    { 
     AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += new ResolveEventHandler(CurrentDomainReflectionOnlyAssemblyResolve); 

     Assembly asm = Assembly.ReflectionOnlyLoadFrom(filename); 

     Type[] types = asm.GetTypes(); 
     foreach (Type type in types) 
     { 
      if (type.IsSubclassOf(typeof(ClientPlugin))) 
      { 
       return true; 
      } 
     } 

     return false; 
    } 
} 

कोड एक प्रॉक्सी है कि मैं अपने कस्टम अनुप्रयोग डोमेन के CreateInstanceFromAndUnwrap माध्यम से बनाए गए के माध्यम से कहा जाता है()। इसका मतलब है कि IsPluginAssembly() को मेरे कस्टम ऐप डोमेन के संदर्भ में निष्पादित किया गया है।

समस्या यह है कि IsSubclassOf() हमेशा कॉल झूठी होती है, भले ही इसे IMHO सच करना चाहिए। प्रश्न में "प्रकार" वास्तव में क्लाइंटप्लगिन से प्राप्त होता है - इसमें कोई संदेह नहीं है।

क्लाइंटप्लगिन को एक अलग निजी असेंबली में परिभाषित किया गया है, जिसे मैं ऊपर कोड कोड खंड में स्पष्ट रूप से हल कर रहा हूं।

मैं if (type.IsSubclassOf(...)) लाइन पर एक ब्रेकपाइंट डाल दिया है और इस बात की पुष्टि यह अभिव्यक्ति गलत होने के लिए:

type.BaseType == typeof(ClientPlugin) 

दूसरी ओर, यह अभिव्यक्ति सत्य है:

type.BaseType.FullName == typeof(ClientPlugin).FullName 

यह संभव कैसे है ? क्या चल रहा है?

अद्यतन: केंट बूगार्ट ने मुझे सही दिशा में इंगित किया। मैंने वेब को थोड़ा और खोजा और this ब्लॉग पोस्ट में चलाया। ऐसा लगता है कि इस काम को करने के लिए मुझे अपने लोड/लोडफ्रम/प्रतिबिंबऑनलीलोड से संघर्षों को हल करना होगा।

उत्तर

7

यह एक अलग संदर्भ में लोड होने के कारण है। आप एक असेंबली कैसे लोड करते हैं (लोड/लोडफ्रम/प्रतिबिंबऑनलीलोड) यह निर्धारित करता है कि यह किस संदर्भ में लोड किया गया है। यह सरल उदाहरण भी समस्या का प्रदर्शन करता है:

using System; 
using System.Reflection; 

class Foo 
{ 
    public static void Main() 
    { 
     var type = typeof(Foo); 
     var reflectionLoadType = Assembly.ReflectionOnlyLoad("ConsoleApplication1").GetType("Foo"); 
     Console.WriteLine(type == reflectionLoadType); //false 
     Console.WriteLine(type.Equals(reflectionLoadType)); //false 

     Console.WriteLine("DONE"); 
     Console.ReadKey(); 
    } 
} 

अधिक जानकारी के लिए here देखें।

2

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

हालांकि मुझे नहीं लगता कि यह वास्तव में आपका मामला है, फिर भी यहां सीखने के लिए एक सबक है - यदि एक डीएलएल दो बार लोड हो जाता है, तो प्रकार भी डुप्लिकेट किए जाएंगे। आपके मामले में मुझे अलग-अलग ऐपडोमेन, या "रिफ्लेक्शनऑनली लोड" पर संदेह होगा, क्योंकि डीएलएल को फिर किसी भी तरह से लोड किया जाता है।

+0

मेरे पास वास्तव में यह समस्या थी, मेरे पास दो फ़ोल्डरों में एक ही डीएलएल की दो प्रतियां थीं। मैन्युअल रूप से "IsSubclassOf" को निष्पादित करते समय, मुझे यह त्रुटि संदेश मिला: 'ServiceCore.BaseService' प्रकार 'ServiceCore.dll' और 'ServiceCore.dll' दोनों में मौजूद है। – vpalmu

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