Hosting MEF in Silverlight

In the desktop today in order to use MEF you are required to manually configure the CompositionContainer (and catalogs) in order to allow the application to discover parts. That container often needs to be exposed (preferably not directly but through a wrapper)
and passed around to other parts of the application that may need it for dynamically composing new parts.

In Silverlight we've introduced a new api called System.ComponentModel.Composition.CompositionInitializer which resides in System.ComponentModel.CompositionInitialization assembly. CompositionInitializer allows parts to
get composed by MEF without having to do any manual bootstrapping as it will automatically configure MEF on demand. With CompositionInitializer any class that has been newed up can have imports and MEF will satisfy them. This means you can use it anywhere
within your Silverlight application. A common place to use it is within your App class in order to import the MainView, or the MainViewViewModel if you are applying an MVVM pattern as in the sample below.

The App imports a MainViewModel. Then in the ApplicationStartup method it calls CompositionInitializer passing
itself_ in order to have it's imports satisfied. This causes MainViewModel to be discovered by MEF and injected with a Logger instance. The application then creates a MainView instance and sets the DataContext to the imported ViewModel.

What's really happening?

The first time SatisfyImports is called, CompositionInitializer is creating a new shared container behind the scenes which it will use for future calls to SatisfyImports. The catalog for that container contains all parts discovered within the assemblies in
the application's main XAP. This means that in addition to the current executing assembly, all referenced assemblies (and their references) also have their parts discovered.

Exports not allowed on the instance passed to SatisfyImports.

Notice that the Application class does not have an export on it.
SatisfyImports is designed to be used ONLY for parts that cannot be discovered by the catalog, meaning they do not have exports. It will throw an exception if you pass it a class that has an
ExportAttribute on it

Using CompositionInitializer from within XAML created elements.

CompositionInitializer is designed to be called mulitple times with it configuring itself on the first call. This makes it ideal to use not only within the root Application class but also within elements created in XAML. For example see the xaml below.

OrderHeader and OrderDetails are nested controls within OrderView which are created in XAML. Both however have their own respective view models which they import. For example below is the OrderHeader. Notice it does not have an export.

In this case OrderHeader is directly importing it's ViewModel versus having it externally wired as in the MainView case. In this case we did this in order to allow it simply to be dropped within XAML without pushing any knowledge of it's wiring up to
the containing control. This type of pattern makes sense in particular for third-party controls using MEF as it simplifies the usage of the control. It's a matter of preference though.

Caveats about using CompositionInitializer.SatisfyImports

By default only assemblies in the current XAP are discovered. You can override this behavior, to learn about this see the overriding host config
topic.

All parts created with CompositionInitializer are held around by MEF until the application shuts down. Thus it is not ideal to use for composing transient multiple-instance parts. For these cases a better choice is to use
ExportFactory

I found the answer to my question in the forums (http://mef.codeplex.com/Thread/View.aspx?ThreadId=214182). There Glenn Block says "Because we want to allow recomposition to occur, we hold on the part so we can recompose it later." He also provides a wrapper that will not do that (http://codepaste.net/mo7afq).

If I use composition initializer to satisfy the imports does the container keep a reference to the object whose imports were satisfied by the call? It seems to us that we are having memory leaks on all objects that have imports.

Can you post to the forums the test you are trying to execute? That exception occurs during recomposition. It sounds like you are trying to add a catalog to the container / CompositionHost after SatisfyImports has already happened and that the imports are probably not recomposable. If you share your VM / unit-test code on our forums we can help. Otherwise you can email me gblock@microsoft.com.

I am running into a problem with MEF inside a Silverlight Unit Test that tests a method in a ViewmModel. I have a reference to the project that contains the ViewModel that I am testing and the Compositions DLLs and yet i get a ChangeRejectedException and it gives a long winded monolog that has no specifics, there must be a way to get the real issue as reflection is groping thru the Assemblies and comes up unsatisfied. MEF works fine when I use in the main assembly that conatins the VM.This exception implies that MEF believes I am doing some kind of dynamic loading wihich I am not!