2013-01-11 25 views
5

अगर मैं एक प्रकार MyClass है, साथक्या एमईएफ निर्यात अनुरोध पर हर बार कैश या खोज रहे हैं?

[Export(typeof(Myclass))] विशेषता रजिस्टर, और

[PartCreationPolicy(CreationPolicy.Shared)]

या

[PartCreationPolicy(CreationPolicy.NonShared)]

और बाद में

कॉल करने का प्रयास compositionContainer.GetExportedValue<Myclass>() कई बार।

प्रश्न: पहली कॉल के साथ, मुझे एमईएफ के माध्यम से मेरी पंजीकृत कक्षा मिल जाएगी - सभी पंजीकृत असेंबली llokup, फिर एक पंजीकृत अनुबंध खोजने की कोशिश कर रहा है। प्रश्न दूसरी बार और इसी तरह है - क्या एमईएफ फिर से वैश्विक लुकअप करेगा या यह कहीं आंतरिक रूप से कैश करेगा?

उत्तर

7

पढ़ MEF वैश्विक देखने फिर से करना होगा या कहीं कैश आंतरिक

हाँ, MEF कुछ कैशिंग perfoms और व्यापक रूप से आलसी आरंभीकरण का उपयोग करता है, तो आप सवाल के बारे में है एमईएफ प्रदर्शन:

1) मेटाडेटा (संगत भागों, निर्यात परिभाषाएं और आयात परिभाषाएं) कैश की गई हैं। उदाहरण: जब CreationPolicy.NonShared, निर्यात मूल्य फिर से और फिर बनाया हो जाता है का उपयोग कर, जब आप इसे का अनुरोध

public object Value 
{ 
    get 
    { 
     if (this._exportedValue == Export._EmptyValue) 
     { 
      object exportedValueCore = this.GetExportedValueCore(); 
      Interlocked.CompareExchange(ref this._exportedValue, exportedValueCore, Export._EmptyValue); 
     } 
     return this._exportedValue; 
    } 
} 
बेशक

,:

public override IEnumerable<ExportDefinition> ExportDefinitions 
{ 
    get 
    { 
     if (this._exports == null) 
     { 
      ExportDefinition[] exports = this._creationInfo.GetExports().ToArray<ExportDefinition>(); 
      lock (this._lock) 
      { 
       if (this._exports == null) 
       { 
        this._exports = exports; 
       } 
      } 
     } 
     return this._exports; 
    } 
} 

2) मूल्यों भी कैश नहीं किया जाता का निर्यात किया। लेकिन इस मामले में भी "ग्लोबल लुकअप" नहीं किया जाता है, क्योंकि मेटाडेटा को कैश किया जाता है।

+0

आपकी व्याख्या के लिए धन्यवाद! –

+0

यह अपूर्ण है, इस अर्थ में कि कुछ लुकअप अभी भी प्रत्येक कॉल पर किया जाता है। तो क्लाइंट-साइड कैशिंग कर रहे हैं यदि 'GetExportedValue' पर कई कॉल किए जाने चाहिए। –

0

यह हर बार एक लुकअप करता है, जब आप [PartCreationPolicy(CreationPolicy.NonShared)] का उपयोग करते हैं। फिर आपको कैशिंग को स्वयं लागू करना होगा।

डिफ़ॉल्ट कार्यान्वयन सिंगलटन पैटर्न का उपयोग कर रहा है। यह गुण [PartCreationPolicy(CreationPolicy.Shared)] के बराबर है। यह सबसे अच्छा अभ्यास है।

अधिक जानकारी के लिए http://blogs.microsoft.co.il/blogs/bnaya/archive/2010/01/09/mef-for-beginner-part-creation-policy-part-6.aspx

+0

"यह हर बार एक लुकअप करता है" - सबूत? – Dennis

+0

मुझे जागने के लिए धन्यवाद। मेरा जवाब अपूर्ण था। मैं विचलित हो गया ... – Jacco

+0

मुझे लगता है कि यह सवाल कंक्रीट निर्यात मूल्य को कैशिंग करने के बारे में नहीं है। – Dennis

0

हालांकि मान/मेटाडाटा आंशिक रूप से कैश किया जा सकता है, कुछ प्रदर्शन परीक्षण करने से पता चलता है कि प्रत्येक लुकअप हर बार GetExportedValue पर कॉल किया जाता है। इसलिए यदि आपके पास कई कॉल हैं जहां आपको मूल्य प्राप्त करने की आवश्यकता है, तो आपको खुद को कैशिंग करना चाहिए। अपने कंप्यूटर, विंडोज 7 x64, .NET 4.5 पर https://gist.github.com/DanielRose/d79f0da2ef61591176ce

:

namespace MEFCachingTest 
{ 
    using System; 
    using System.ComponentModel.Composition; 
    using System.ComponentModel.Composition.Hosting; 
    using System.ComponentModel.Composition.Primitives; 
    using System.Diagnostics; 
    using System.Reflection; 

    public static class Program 
    { 
     public static CompositionContainer Container { get; set; } 
     public static ComposablePartCatalog Catalog { get; set; } 

     public static ExportedClass NonCachedClass 
     { 
      get 
      { 
       return Container.GetExportedValue<ExportedClass>(); 
      } 
     } 

     private static ExportedClass cachedClass; 
     public static ExportedClass CachedClass 
     { 
      get 
      { 
       return cachedClass ?? (cachedClass = Container.GetExportedValue<ExportedClass>()); 
      } 
     } 

     public static void Main() 
     { 
      Catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); 
      Container = new CompositionContainer(Catalog); 

      const int Runs = 1000000; 
      var stopwatch = new Stopwatch(); 

      // Non-Cached. 
      stopwatch.Start(); 
      for (int i = 0; i < Runs; i++) 
      { 
       var ncc = NonCachedClass; 
      } 

      stopwatch.Stop(); 
      Console.WriteLine("Non-Cached: Time: {0}", stopwatch.Elapsed); 

      // Cached. 
      stopwatch.Restart(); 
      for (int i = 0; i < Runs; i++) 
      { 
       var cc = CachedClass; 
      } 

      stopwatch.Stop(); 
      Console.WriteLine(" Cached: Time: {0}", stopwatch.Elapsed); 
     } 
    } 

    [Export] 
    [PartCreationPolicy(CreationPolicy.Shared)] 
    public class ExportedClass 
    { 
    } 
} 

अधिक विविधताओं के लिए, इस सार को देखो।2:

Non-Cached: Time: 00:00:02.1217811 
    Cached: Time: 00:00:00.0063479 

NuGet से MEF 2 का उपयोग करना:

Non-Cached: Time: 00:00:00.2037812 
    Cached: Time: 00:00:00.0023358 

वास्तविक आवेदन जहाँ मैं काम में, इस आवेदन 6x धीमी कर दिया।