I use a static variable for holding the count of objects. In constructor I increase this variable. This way I know how many instances of the object are created.
After using the objects, they are leaved dereferenced.
I'm doubtful if MEF
is holding references to these objects so I force GC
to do a clean up (Using GC.Collect()
method). I expect on next object creation this variable start from zero but it resumes from last number. I put a logging mechanism in destructor
for tracing, and objects are destroyed only after the application is closed.
Can I assume MEF
has created other references to those objects ?
I use MEF
and ExportFactory
for creating my objects
Edit:
Maybe something with ExportLifetimeContext
should be done ?
I force GC to do a clean up
If MEF still has references to the objects, then obviously this doesn't do anything. If the objects have become garbage, then the garbage collector will automatically collect them - asking it to do that explicitly is just a hint that might be ignored. Either way, this is not necessary.
I put a logging mechanism in destructor for tracing, and objects are destroyed only after the application is closed. Can I assume MEF has created other references to those objects ?
MEF will hold references to created objects so that it is able to repeatedly return the same reference when you ask for an export. To ask MEF to abandon these references, you should call CompositionContainer.Dispose
. Obviously you cannot reuse the container any more after that, though you could create a new one.
MEF is also the owner of any IDisposable
objects it creates. This means that when you dispose the container, it will call Dispose
on any such objects before abandoning the reference.
It is preferable to rely on calls to Dispose
to perform cleanup, rather than to use finalizers. There is no guarantee that finalizers are run at all.
edit:
I need to destroy the object after using it. But I don't want to destroy the container. I want MEF as a factory for creating new instances of asking part, and the caller should be capable of destroying the object when he doesn't need anymore. Can you help with this ?
This is what ExportFactory is for. (It was formerly called PartCreator
). Unfortunately it is not yet available in .NET 4, unless you use Silverlight. You can use the preview releases from codeplex to already give it a try.
If you don't want to use the preview releases of MEF, you might be able to implement something like ExportFactory
yourself by creating factory classes that wrap the container and by using its GetExport
and ReleaseExport
methods to acquire and release objects. Don't forget to set a PartCreationPolicy
if you need to create multiple instances of the same part.
edit 2:
I somehow missed that you were already using ExportFactory
all along. You simply need to call ExportLifeTimeContext.Dispose
when you're done with the object!
The timely "destruction" (that is finalization) of objects in the CLR is not a good thing to rely on. If you're doing this for debugging purposes, there's no need. You can find out how many objects of some type are still in existence by following the instructions in my answer to this question:
Memory Leaks in C# WPF
If you are genuinely trying to make your software's behaviour depend on a count of the number of instances of a class that have not been reclaimed by the GC, then you need to rethink your design. There will be several better ways of achieving what you want.
For shared objects, MEF will keep references to them as long as the container is alive. You can have NonShared parts be disposed early in the right circumstances. If you are using ExportFactory, you need to dispose the ExportLifetimeContext returned by the CreateExport method to dispose any NonShared parts created as part of the request. If you called a GetExport method on the container, you can call the ReleaseExport method. If you got the exports some other way (ie SatisfyImports or something), there isn't a way to release them so you may want to refactor your application to use ExportFactory or GetExport.
MEF now has a desktop version which supports ExportFactory
. Although the name has 'export' word, you should implement it where you are doing your 'imports'. A call to CreateExport()
method for creating a new instance of your part will return an ExportLifetimeContext<T>
an this object has a Dispose()
method which could be used later for releasing exported object. This method would call your object Dispose()
automatically and you don't need to call it manually.
This behavior is because the container is the owner of created objects by itself and even with a reference to these objects calling their Dispose()
has no effect on them.