Custom ExportProvider and MEF recomposition

I've got a question about custom ExportProviders in combination with MEF recomposition. I've got an ExportProvider which finds exports through a configuration file. This is parsed using LINQ to XML on creation of the exportprovider into a Dictionary. A dictionary
of contract names and related types. The GetExportsCore method is implemented in such a way that when it is called with an ImportDefinition, it looks in the Dictionary, finds the type belonging to the contractname of the ImportDefinition and creates the Export
and ExportDefinition objects. So far so good and everything works as expected.

I enhanced the ExportProvider with a FileSystemWatcher, which monitors the configurationfile. When it changes, it parses the file again, finds out which exportdefinitions have been added and which have been removed and fires the OnExportsChanging and OnExportsChanged
events accordingly. This also works correctly as I can see the events "bubble up" to the CompositionContainer. Whenever I fire these events in the ExportProvider, they are automatically fired in the CompositionContainer.

Now the problem:

I hoped :) that calling the OnExportsChanging and the OnExportsChanged methods in my ExportProvider, would be enough for MEF to recomposition all the parts that have been composed, but nothing really happens except for the container firing the events. I
tried to delve into the source code and it seems that such "automatic" recomposition is only possible for catalogs (I thinks it's actually the CatalogExportProvider which does this). Am i correct? Isn't there an easy way for custom ExportProviders
to trigger recomposition when their Exports change?

If i'm correct, are there any plans to implements this before the final version ships?

Recomposition should work fine for custom export providers as well. Are you sure that you are firing the OnExportsChanging event properly? That is the key place where the recomposition should occur. Perhaps if you post your code we might be able to point
out what could be happening.

Thanks for your answer. Are you sure about the ExportProvider and the recomposition? When I went through the source code of the MEF framework, the only thing doing something when the OnChanging event fires is the CatalogExportProvider, which is wrapped around
a catalog when you create the CompositionContainer. That's why I assumed recomposition only works for catalogs implementing a certain interface..... I don't want to question your knowledge, I'm just curious were the handling of the OnChanging event of a custom
exportprovider is implemented, maybe I missed it. As I said, when my custom ExportProvider fires these events, the container also fires them.

I should mention that the recomposition wanted is a single import recomposition, so the value imported needs to be replaced with the new value. It;s not an IEnumerable. I'm not at work today, so I will post the code tomorrow.

The real magic of recomposition happens inside the ImportEngine since it is the one that knows about and controls the imports. When a custom export provider triggers the OnExportsChanged/ing events the CompositionContainer will propagate those events. The
ImportEngines which are used by our two standard ExportProviders (CatalogExportProvider and ComposablePartExportProvider) both subscribe to the OnExportsChanging event of the CompositionContainer so when the container fires that event they receive it and update
the appropriate imports. I am describing this from memory but I believe that is basically how it works, hopefully it makes some since.

Out of curiosity for the imports that you expect to get recomposed are they on parts that live in either a CatalogExportProvider or ComposablePartExportProvider? If not and they are from your custom export provider how are you actually satisfying the
imports for them initially?

The imports that I expect that need to get recomposed are on a part which I supply to the CompositionContainer with the ComposeParts() method. The CompositionContainer is created and given my custom exportprovider in the constructor.
The parts that the exportprovider provides don't have any imports on them.

Im sorry that I still can't post the code today, so I'll hopefully post that tomorrow.

Thanks to your help i fixed the issue! When you said that most of the magic happens inside the ImportEngine, I decided to put a few break points there. I ultimately breaked into the GetImportsAffected method, which returned none. I found out that this method
uses the ImportDefintion.IsConstraintSatisfiedBy() method. Breaking into that method of the ContractBasedImportDefinition, it seemed that an ExportDefinition satisfies an ImportDefinition if both the the contractname and the metadata match. This was logical
and was as I assumed. I had no metadata in my ExportDefintions so the MetaData dictionary of an ExportDefinition was empty. But the ContractBasedImportDefinition demands that an ExportDefinition has a metadata keyvalue, where the key is "CompositionConstants.ExportTypeIdentityMetadataName"
and the value is also the contractname. After putting this metadata in my exportdefinitions, all worked as expected. I think this should be mentioned in the documentation, as it applies to every custom ExportProvider you make in combination with the attribute
based programming model.

Recomposition should work fine for custom export providers as well. Are you sure that you are firing the OnExportsChanging event properly? That is the key place where the recomposition should occur. Perhaps if you post your code we might be able to point
out what could be happening.

Hello,

I've spent several hours already trying to resolve issue with custom provider and recomposition in Silverlight 4. Here's the details for implementation:

At this point nothing happens. The "Activities" property is not recomposed. I've tried checking "OnImportsSatisfied" method but it's not called and property contains only 2 instances.

However if I call "_container.ComposeParts(this)" from code the property is refreshed with "3" instances as expected.

What I really need is "Activities" property to be recomposed automatically whenever I add new export to my custom provider. Wiring "Changed" event for the provider and calling "Container.ComposeParts" manually is not an option
for me as recomposition should take place in various different places.

I would be gratefull if you could give me at least some sort of workaround