Object life-time problem using ExportFactory

Dec 6, 2010 at 4:56 PM

I use MEF and ExportFactory for creating new instances of my parts on a desktop application. My choice is lazy instanciation and early destroying objects after using them.The problem is object destructor doesn't call after a GC.Collect(), although there is no reference to objects. These objects destructors are called upon exiting the application (traced by a logger). It means MEF holds some reference to them. Is this a bug or it is by design ? how to avoid this ?

 

my simplified code:

// creating container

directoryCatalog = new DirectoryCatalog("C:\Parts");

container = new CompositionContainer(directoryCatalog);
container.ComposeParts(this);

// ... Later on this class we import parts like this:

 [ImportMany(typeof(IPart))]
 private IEnumerable<ExportFactory<IPart, IDictionary<string, object>>> Parts
 {
       get;
       set;
 }

// Getting a part

public IPartProvider GetPart(String name)
{
    foreach (var part in Parts)
        if (part.Metadata["Name"] == name)
            return part.CreateExport().Value as IPart;
}

Now inside a part we have:

[Export(typeof(IPart))]
[ExportMetadata("Name", "Test")]
class Part : IPart, IDisposable
{
     // ...

     ~Part()
     {
          // Log object is destroyed
     }
}


The log is written only after closing the application. I expect the log when I dereference all instances and calling a GC.Collect()

 

 

 

        private IDownloadProvider GetProvider(String host)
        {
            foreach (var downloadProvider in DownloadProviders)
                if (host.EndsWith(downloadProvider.Metadata[PLUGIN_DOMAIN] as String))
                    return downloadProvider.CreateExport().Value as IDownloadProvider;

            // Get ready for 'stack over flow' !
            return GetProvider(DEFAULT_DOWNLOAD_PROVIDER);
        }
Dec 6, 2010 at 6:09 PM

I tried ExportLifetimeContext  and Dispose of Parts created with it, but the problem exist.

Dec 14, 2010 at 10:09 AM

Thanks guys, I cannot read all of your answers but I tired this and problem solved : Dispose ExportLifetimeContext object instead of real object (ExportLifetimeContext.Value)