2009-05-12 11 views
16

मेरी समस्या है:सी # प्रतिबिंब: समाधान में सभी * सक्रिय असेंबली प्राप्त करें?

मेरे पास 2 परियोजनाएं हैं - एक 'सामान्य' परियोजनाएं जिसमें लाइब्रेरी जैसे सभी प्रकार के समर्थन कोड के साथ कार्य करता है, और वास्तविक कार्यक्रम जो इसकी कई कॉलों में प्रोजेक्ट का उपयोग करता है। हम इन परियोजनाओं को "आम" और "कार्यक्रम" कहते हैं। वे दोनों एक ही समाधान में हैं।

"सामान्य" के भीतर, मेरे पास एक उदाहरण बनाने जैसे कॉमो प्रतिबिंब कार्यों के लिए एक कक्षा है। अगर मैं GetExecutingAssembly को कॉल करता हूं, तो यह सभी "सामान्य" प्रकार प्राप्त करता है, हालांकि जब मैं GetEntryAssembly का उपयोग करता हूं तो मुझे "प्रोग्राम" प्रकार मिलते हैं।

जबकि मैं निश्चित रूप से कोड के 2 सेट के साथ काम करने के लिए कोड संपादित कर सकता हूं, मुझे ऐसी स्थिति से डर है जहां समाधान में केवल 2 परियोजनाएं हैं - कहें 5 (पता नहीं क्यों, लेकिन चलो बस अभी के लिए जाओ), और मुझे डर है कि GetExecutingAssembly और GetEntryAssembly को कॉल करने से पूरे कार्यक्रम में सभी प्रकार नहीं मिलेंगे।

क्या कुछ और है जो मैं समाधान में सभी प्रकार प्राप्त करने के लिए कर सकता हूं?

उत्तर

49
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); 

यह वर्तमान ऐपडोमेन में सभी भारित असेंबली प्राप्त करेगा।

जैसा कि टिप्पणियों में उल्लेख किया गया है, कई ऐपडोमेन को जन्म देना संभव है, इस मामले में प्रत्येक के पास अपनी स्वयं की असेंबली हो सकती है। ऐसा करने का तत्काल लाभ यह है कि आप युक्त ऐपडोमेन को उतारकर असेंबली को अनलोड कर सकते हैं।

+3

मई या 1 के अधीन काम नहीं कर सकता) यदि एप्लिकेशन को सभी यदि एक से अधिक AppDomains 2) spawns रेफ असेंबली को इस बिंदु से पहले लोड किया गया है – Gishu

+1

बिल्कुल सही, धन्यवाद! – cyberconte

+0

@ गिशू: "यदि इस बिंदु से पहले सभी रेफ असेंबली लोड हो चुकी हैं" तो निश्चित रूप से यह सुनिश्चित नहीं है कि आप इसका क्या मतलब रखते हैं। क्या आप विस्तार से समझा सकते हैं? – bsneeze

7

असेंबलीआरएफ मेटाडेटा प्रविष्टियों को बंद करने के लिए GetReferencedAssemblies के बारे में कैसे? 'समाधान' ऐसा कुछ नहीं है जिसे सीएलआर जानता है या परवाह करता है .. यह असेंबली में काम करता है।

private static List<Assembly> GetListOfEntryAssemblyWithReferences() 
{ 
    List<Assembly> listOfAssemblies = new List<Assembly>(); 
    var mainAsm = Assembly.GetEntryAssembly(); 
    listOfAssemblies.Add(mainAsm); 

    foreach (var refAsmName in mainAsm.GetReferencedAssemblies()) 
    { 
    listOfAssemblies.Add(Assembly.Load(refAsmName)); 
    } 
    return listOfAssemblies; 
} 

चेतावनियां:
1. आप अभी भी 2. फिल्टर करने के लिए कोर विधानसभाओं प्रणाली की जरूरत है * यह सिर्फ एक स्तर रेफरी श्रृंखला में गहरी हो जाता है .. लेकिन रिकर्सिवली किया जा सकता है - और अधिक कोड के साथ।।

5

इसके अलावा: कुछ असेंबली सीधे लोड नहीं होते हैं, इसलिए आपको ऐपडॉमेन के असेंबली लोड इवेंट पर इवेंट हैंडलर भी रखना चाहिए।

AppDomain.CurrentDomain.AssemblyLoad += .... 
29

यह एक वास्तव में वर्ष सवाल है, लेकिन भविष्य में संदर्भ के लिए यहाँ एक पूर्ण कार्यान्वयन है:

public static IEnumerable<Assembly> GetAssemblies() 
    { 
     var list = new List<string>(); 
     var stack = new Stack<Assembly>(); 

     stack.Push(Assembly.GetEntryAssembly()); 

     do 
     { 
      var asm = stack.Pop(); 

      yield return asm; 

      foreach (var reference in asm.GetReferencedAssemblies()) 
       if (!list.Contains(reference.FullName)) 
       { 
        stack.Push(Assembly.Load(reference)); 
        list.Add(reference.FullName); 
       } 

     } 
     while (stack.Count > 0); 

    } 
+0

अच्छा, साझा करने के लिए धन्यवाद - बस मुझे जो चाहिए था। – Dav

+0

@ डेव आपका स्वागत है! –

+0

किसी सूची के हैशसेट इंस्टेस का उपयोग करने का प्रयास करें। – AgentFire

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