2012-10-18 12 views
5

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

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

मैंने पाया कि कुछ ऐसा है जो मैंने अभी लिखा है, लेकिन MEF CachedAssemblyCatalog - Lazy Loading of Assemblies में इसके बारे में पूछने के बाद, मुझे एहसास हुआ कि यह कोड स्थिर नहीं माना गया है और एमईएफ टीम द्वारा बनाए रखा नहीं जा रहा है, इसलिए मेरे पास इसका इस्तेमाल न करने का फैसला किया।

  • अपने पूरे विधानसभा लोड किए बिना प्लगइन विधानसभाओं 'निर्यात मेटाडाटा उपयोग करने में सक्षम होने के नाते:

    मेरा प्रश्न मैं इस व्यवहार को कैसे तो प्राप्त कर सकते हैं।

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

के रूप में किसी भी मौजूदा MEF कार्यक्षमता खोने मैं एक समाधान आवश्यक होता है कि पहले से प्लग-इन को पार्स एक मेटाडाटा विधानसभा, एक्सएमएल फ़ाइल या whatnot बनाने के लिए साथ पूरी तरह से ठीक हूँ।

उत्तर

2

यदि आप असेंबली लोड करने में देरी के बाद ही हैं तो आप this question के समाधानों का संभावित रूप से उपयोग कर सकते हैं। आपको उस समाधान में पुनर्प्राप्त की गई सभी जानकारी को पकड़ने की आवश्यकता नहीं होगी। शायद केवल अनुबंध का नाम, असेंबली का नाम और क्या यह हिस्सा अनुबंध निर्यात या आयात कर रहा है या नहीं। तो फिर तुम इस तरह की एक सूची है कि विधानसभाओं लोड करता है के रूप में आप उन्हें जरूरत, उदाहरण के लिए लिख सकते हैं:

public sealed class DelayLoadingCatalog : ComposablePartCatalog 
{ 
    // List containing tuples which have the 'contract name' 
    // and the 'assembly name' 
    private readonly List<Tuple<string, string>> m_Plugins 
     = new List<Tuple<string, string>>(); 
    private readonly Dictionary<string, AssemblyCatalog> m_Catalogs 
     = new Dictionary<string, AssemblyCatalog>(); 

    public DelayLoadingCatalog(IEnumerable<Tuple<string, string>> plugins) 
    { 
     m_Plugins.AddRange(plugins); 
    } 

    public override IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>> GetExports(ImportDefinition definition) 
    { 
     var partsToLoad = m_Plugins 
      .Where(t => t.Item1.Equals(definition.ContractName)); 
     foreach (var part in partsToLoad) 
     { 
      if (!m_Catalogs.ContainsKey(part.Item2.Name)) 
      { 
       var assembly = Assembly.Load(new AssemblyName(part.Item2.Name)); 
       m_Catalogs.Add(part.Item2.Name, new AssemblyCatalog(assembly)); 
      } 
     } 

     return m_Catalogs.SelectMany(p => p.Value.GetExports(definition)); 
    } 

    public override IQueryable<ComposablePartDefinition> Parts 
    { 
     get 
     { 
      throw new NotImplementedException(); 
     } 
    } 
} 

आप तो इस

class Program 
{ 
    public void Init() 
    { 
     var domainSetup = new AppDomainSetup 
     { 
      ApplicationBase = Directory.GetCurrentDirectory(), 
     }; 

     var scanDomain = AppDomain.CreateDomain(
      "scanDomain", 
      null, 
      domainSetup); 
     var scanner = scanDomain.CreateInstanceAndUnwrap(
      typeof(MyScanner).Assembly.FullName, 
      typeof(MyScanner).FullName) as MyScanner; 
     var plugins = scanner.Scan(myPluginsPath); 

     // Make sure we don't have the assemblies loaded anymore ... 
     AppDomain.Unload(scanDomain); 

     var catalog = new DelayLoadingCatalog(plugins); 
     var container = new CompositionContainer(catalog); 

     container.ComposeParts(this); 
    } 

    [Import("MyCoolExport")] 
    public object MyImport 
    { 
     get; 
     set; 
    } 
} 

उदाहरण DelayLoadCatalog के रूप में बहुत होशियार नहीं है की तरह उपयोग कर सकते हैं जो यह टुपल्स की सूची के माध्यम से खोज रहेगा। हालांकि कोड को अनुकूलित करना बहुत मुश्किल नहीं होना चाहिए। उदाहरण के लिए आप जांच सकते हैं कि सभी असेंबली लोड हो चुकी हैं और उस बिंदु पर उस सूची के माध्यम से खोजना बंद कर दें।

+0

अरे पेट्रिक, आपकी मदद के लिए बहुत बहुत धन्यवाद! मैंने आपके द्वारा पहले से जुड़े प्रश्न पर ठोकर खाई और इससे मुझे इस समस्या को हल करने में बहुत मदद मिली। जो मैंने किया वह कुछ ऐसा था जो आपने वहां वर्णित किया था - मैंने डेटा को एक फ़ाइल में क्रमबद्ध किया और उस फ़ाइल का उपभोग करने वाली एक नई सूची बनाई। इस तरह, मेटाडेटा समेत सभी निर्यात उपलब्ध हैं, और 'रिफ्लेक्शनमोडेल सर्विसेज' एपीआई का उपयोग करके, सब कुछ आलसी लोड किया गया था। यह मेरी आवश्यकताओं के लिए जाने का सबसे अच्छा तरीका प्रतीत होता है। मुझे आशा है कि मेरे पास इस प्रश्न का उत्तर देने के लिए कुछ समय होगा जो मैंने किया है। एक बार फिर धन्यवाद! –

0

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

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