Value cached?

Jun 3, 2010 at 6:09 PM

Hi,
I've written a custom export provider which manages plugin's ctor expcetion

protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition)
        {
            Export exp;
            List<Export> exports = new List<Export>();
            
            foreach (var export in _exportProvider.GetExports(definition, atomicComposition))
            {
                try
                {
                    exp = new Export(export.Definition, () => export.Value);
                    object value = exp.Value;

                    exports.Add(export);
                }
                catch (CompositionException ex)
                {
                    OnPluginError(new PluginErrorEventArgs(ex));
                    logger.Error(ex.Message);
                }
                catch (Exception ex)
                {
                    OnPluginError(new PluginErrorEventArgs(ex));
                    logger.Error(ex.Message);
                }
            }

            return exports;
        }

So I try to get the plugin's instance with exp.Value and the plugin is created.
When the composition container imports my plugins in a IEnumerable<Lazy<T, TMetadata>> the plugin's ctor isn't called another time accessing to Lazy's Value property...

Is MEF caching my plugin?

Thanks
Federico

Developer
Jun 4, 2010 at 5:17 PM

I'm not sure what your _exportProvider type is but if it is a CatalogExportProvider and the Export coming from it is on a part with a CreationPolicy.Shared or .Any, which is the default, then yes MEF is caching that value. For it to be a new instance each time either the part you want it coming from has to be marked as CreationPolicy.NonShared or it has to be CreationPolicy.Any and the ImportDefinition must require ImportCreationPolicy=NonShared (have a look at RequiredCreationPolicy on ContractBasedImportDefinition).

Jun 8, 2010 at 6:35 AM

Thanks :)

Federico

Jun 8, 2010 at 10:17 PM

Why have I to set the SourceProvider's CatalogExportProvider property? I have all my exports in the AggregateCatalog that I pass to the ExportProvider's constructor

public PluginExportProvider(ComposablePartCatalog catalog) : base()
        {
            this._exportProvider = new CatalogExportProvider(catalog);
            this._exportProvider.ExportsChanged += (s, e) => OnExportsChanged(e);
            this._exportProvider.ExportsChanging += (s, e) => OnExportsChanging(e);
        }

Thanks
Federico

Developer
Jun 9, 2010 at 3:29 AM

Behind the scenes the CatalogExportProvider is using an ImportEngine which is in charge of satisfying the imports on the parts the CatalogExportProvider hands out and the SourceProvider is export provider that the import engine uses to query for exports to satisfy those imports. The SourceProvider is generally set to the outer most layer which is the CompositionContainer instance. If all your exports are in the AggregateCatalog that is used by the CatalogExportProvider you could set the SourceProvider to the CatalogExportProvider itself but then you would never see any exports that are added directly the container using container.Compose(CompositionBatch).

 

Jun 9, 2010 at 8:25 AM

Thanks again :)