2010-04-17 16 views
12

हम अपने आवेदन के लिए प्लगइन ढांचे को लागू करते हैं और असेंबली का उपयोग करके प्लगइन असेंबली लोड करते हैं। लोड से। हम फिर GetTypes() का उपयोग करते हैं और समर्थित इंटरफेस के लिए प्रत्येक प्लगइन फ़ाइल के साथ प्रकारों की जांच करते हैं।असेंबली। गेट टाइप्स() - प्रतिबिंब टाइप टाइपऑक्सप्शन

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

हम एक कोड बेस (appA_1 और appA_2) से सॉफ़्टवेयर के दो संस्करण बनाते हैं।

प्लगइन लोड हो रहा है जब प्लगइन प्लगइन फ़ाइल के रूप में एक ही समय में बनाया गया अनुप्रयोग द्वारा लोड किया जाता है। हालांकि अगर हम appA_2 बनाते हैं और ऐपजेयर के प्लगइन फ़ोल्डर को इंगित करते हैं, तो GetTypes() को कॉल करते समय हमें अपवाद मिलता है।

हमारे कोड का एक मूल संस्करण है;

var pluginAssembly = Assembly.LoadFrom(FileName);  
foreach (var pluginType in pluginAssembly.GetTypes()) 
{ 

हमें "प्रतिबिंब टाइप टाइप अपवाद" अपवाद मिलता है।

यह संबंधित है क्योंकि हम चाहते हैं कि हमारा एप्लिकेशन किसी भी प्लगइन के प्रकार को लोड करने में सक्षम हो। क्या हम कुछ खो रहे हैं?

संपादित करें: लोडर अपवादों के माध्यम से पुनरावृत्ति के बाद हमने पाया है कि एक फ़ाइल libPublic.dll है जो System.IO.FileNotFoundException अपवाद उत्पन्न करती है। अजीब बात यह है कि यह फ़ाइल एप्लिकेशन निर्देशिका में रहती है और प्लगइन को प्रोजेक्ट फ़ाइल में संदर्भित किया जाता है।

संपादित करें 2: अपवाद लॉग हम निम्नलिखित मिल में "विधानसभा नाम मुकाबले बेमेल में हुई: संशोधन संख्या"

+0

अपवाद संदेश क्या है? क्या अपवाद में आंतरिक अपवाद है? इसका संदेश क्या है? – dtb

+0

कोई कारण नहीं है कि आप मौजूदा फ्रेमवर्क जैसे एमईएफ का उपयोग नहीं कर रहे हैं? – dtb

+0

एमईएफ का उपयोग करते समय भी आप इस तरह की समस्याएं पैदा कर सकते हैं, हालांकि एमईएफ निश्चित रूप से गंदे काम की देखभाल करने के लिए आसान है। –

उत्तर

14

कुछ बातें:

  • सुनिश्चित करें कि आप डॉन ' प्लगइन निर्देशिका में डुप्लिकेट असेंबली नहीं है (यानी असेंबली जिन्हें आप पहले से ही अपने ऐप निर्देशिका से अपने मुख्य ऐप में लोड कर रहे हैं।) अन्यथा, जब आप अपनी प्लगइन लोड करते हैं, तो यह एक ही असेंबली की एक अतिरिक्त प्रति लोड कर सकता है। इससे मजेदार अपवाद हो सकते हैं जैसे:

    ऑब्जेक्ट ('MyObject' प्रकार का प्रकार 'MyObject' प्रकार का नहीं है।

  • जब एक प्रकार instantiating आप अपवाद हो रही है, तो आप AppDomain.AssemblyResolve को संभालने के लिए आवश्यकता हो सकती है:

    private void App_Startup(object sender, StartupEventArgs e) 
    { 
        // Since we'll be dynamically loading assemblies at runtime, 
        // we need to add an appropriate resolution path 
        // Otherwise weird things like failing to instantiate TypeConverters will happen 
        AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; 
    } 
    
    private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 
    { 
        var domain = (AppDomain) sender; 
    
        foreach (var assembly in domain.GetAssemblies()) 
        { 
         if (assembly.FullName == args.Name) 
         { 
          return assembly; 
         } 
        } 
    
        return null; 
    } 
    

मुझे पता है यह CLR बताने के लिए है करने के लिए थोड़ा अजीब है कि, एक असेंबली को हल करने के लिए, उस नाम के साथ असेंबली ढूंढें जिसे हम हल करने के लिए उपयोग कर रहे हैं, लेकिन मैंने इसके बिना अजीब चीजें देखी हैं। उदाहरण के लिए, मैं प्लगइन असेंबली से प्रकारों को तुरंत चालू कर सकता हूं, लेकिन अगर मैंने TypeDescriptor.GetConverter का उपयोग करने का प्रयास किया है, तो उसे कक्षा के लिए TypeConverter नहीं मिलेगा, भले ही यह कक्षा पर Converter विशेषता देख सके।


अपने संपादन को देखते हुए, यह शायद नहीं क्या अपने वर्तमान अपवाद पैदा ही आप बाद में के रूप में आप अपने प्लग-इन के साथ काम इन मुद्दों में चला सकते हैं है।

+1

आप कमाल कर रहे हैं! मेरे पास डुप्लिकेट असेंबली समस्या थी, इसलिए इस जवाब ने मुझे बचाया! – JoeCool

+0

इसने मेरी समस्या को भी हल किया। मैं अपना प्लग-इन लोड कर रहा था जिसने एक कस्टम यूआईटीपीएडिटर और टाइप कन्वर्टर्स का खुलासा किया और मेरे प्रकार लोड होने पर, संपादक/कनवर्टर्स तत्काल नहीं होंगे। इसके अतिरिक्त, मेरे प्लग-इन एप्लिकेशन के सापेक्ष एक उप निर्देशिका में स्थित थे, और अजीब रूप से पर्याप्त है, अगर मैं प्लग-इन को उसी निर्देशिका में डालता हूं जैसे मेजबान एप्लिकेशन ने यह ठीक काम किया है। इस समाधान ने प्लग-इन को उनके स्थान के बावजूद काम करने में मदद की। – Mike

+0

आप बिल्कुल सही हैं। मैं भी बाल आवेदन में एक असेंबली लोड कर रहा था जो पहले से ही मूल आवेदन में मौजूद है। जब मैं AppDomain.CurrentDomain.GetAssemblies() के साथ लोड किया गया तो मुझे असेंबली मिली और GetTypes() में लोडर समस्या का समाधान किया। बहुत बहुत धन्यवाद :) @Dan Dryant –

0

आपको एक असेंबली संस्करण मेल नहीं मिला है। चूंकि आपके प्लगइन्स इस libPublic.dll का संदर्भ लेते हैं, इसलिए आपको इसे सावधानी से संस्करण करना होगा और विशेष रूप से इसके संशोधन/निर्माण/आदि को टक्कर नहीं देना चाहिए। प्रत्येक संकलन पर संख्याएं।

2

इस पोस्ट के लिए धन्यवाद मैं ReflectionTypeLoadException को हल कर सकता हूं कि मुझे UITypeEditor में मिल रहा था। यह एक कस्टमर लाइब्रेरी के डिजाइनर असेंबली (डिज़ाइन-टाइम पर डिज़ाइन किया गया स्मार्ट-टैग) है, जो कुछ प्रकार के लिए स्कैन करता है।

/// <summary> 
/// Get the types defined in the RootComponent. 
/// </summary> 
private List<Type> getAssemblyTypes(IServiceProvider provider) 
{ 
    var types = new List<Type>(); 
    try 
    { 
     IDesignerHost host = (IDesignerHost)provider.GetService(typeof(IDesignerHost)); 
     ITypeResolutionService resolution = (ITypeResolutionService)provider.GetService(typeof(ITypeResolutionService)); 
     AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => 
     { 
      foreach (var assembly in ((AppDomain)sender).GetAssemblies()) 
      { 
       if (assembly.FullName == args.Name) 
       { 
        return assembly; 
       } 
      } 

      return null; 
     }; 

     Type rootComponentType = resolution.GetType(host.RootComponentClassName, false); 
     types = rootComponentType.Assembly.GetTypes().ToList(); 
    } 
    catch 
    { 
    } 

    return types; 
} 
+0

IServiceProvider कहां से आता है? यह कैसे प्राप्त किया जा सकता है? – Pangamma

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