This project has moved. For the latest updates, please go here.

Importing the CompositionContainer

May 13, 2010 at 3:12 PM
Hello, - I'm trying out the WAF book sample code and wondering why we need to import the CompositionContainer. Can the reference to bookListView not be obtained by MEF? - I'm using mefx to check out the exports/imports. This seems to be a problem with Net 4 as when I try it I get messages saying the parts cannot be constructed as the CompositionContainer is not available. Anyone seen this problem and anyone have any ideas how to fix it. mefx is a great tool but seems to get upset when the CompositionContainer is one of the imports. [ImportingConstructor] public BookController(CompositionContainer container, IEntityService entityService, ShellViewModel shellViewModel, BookViewModel bookViewModel) { this.container = container; this.entityService = entityService; this.shellViewModel = shellViewModel; this.bookViewModel = bookViewModel; this.addNewCommand = new DelegateCommand(AddNewBook, CanAddNewBook); this.removeCommand = new DelegateCommand(RemoveBook, CanRemoveBook); this.lendToCommand = new DelegateCommand(LendTo, CanLendTo); } public void Initialize() { bookViewModel.LendToCommand = lendToCommand; bookViewModel.PropertyChanged += BookViewModelPropertyChanged; IBookListView bookListView = container.GetExportedValue<IBookListView>();
May 13, 2010 at 3:26 PM
Just checked out putting the reference to bookListView into the ImportingConstructor. Seems to work fine. So now I'm really wondering why import the CompositionContainer [ImportingConstructor] public BookController( CompositionContainer container, IEntityService entityService, ShellViewModel shellViewModel, BookViewModel bookViewModel, IBookListView bookListView) {
May 14, 2010 at 9:00 AM

As I understand it, you need to hold a reference to the CompositionContainer if your controller/viewmodel is responsible for creating some child viewmodels or views after a particular event occurs (i.e. not at construction).

Clearly you could import these types on construction of the parent view model and so on, all the way down the graph, but this might be an expensive operation which includes instantiating views and viewmodels which may never be used.

In .NET 4 and more recent releases of MEF we have Lazy<T>. This would resolve the instantiation problem.

Coordinator
May 15, 2010 at 10:52 AM

The Managed Extensibility Framework (MEF) in .NET 4 doesn’t support the factory (or dynamic instantiation) approach out of the box.

Example: The LendToWindow class in the BookLibrary sample is a modal dialog. In WPF it’s not possible to reopen a dialog when the user has closed the Window. You need to create a new instance of LendToWindow. That’s the reason why I use:

[PartCreationPolicy(CreationPolicy.NonShared)]

in the Export definition of the LendToWindow class.  This way I get always a new instance of LendToWindow when I request the ILendToView:

container.GetExportedValue<ILendToView>()

Microsoft has introduced an alternative approach in the MEF implementation for Silverlight. This implementation provides the ExportFactory<T> class. See also: http://mef.codeplex.com/wikipage?title=PartCreator&referringTitle=Guide.

Unfortunately, this doesn’t work in the .NET 4 MEF implementation. Therefore, I have to register the CompositionContainer and use it in a ServiceLocator fashion.

May 18, 2010 at 3:07 AM
 

jbe2277,

Have you tried using mefx to check out the MEF import / exports on your application samples. When I tried it showed all of your container imports as unsatisfied and produced a lot of error messages. I'm wondering if you can think of any solution for this.

Thanks,

Richard

 

Coordinator
May 20, 2010 at 7:46 PM

Hi Richard,

Mefx does only work right when all Exports and Imports are defined in declarative way (e.g. via Attributes). This is because Mefx does a static code analysis and so it doesn’t see when the CompositionContainer is used for dynamic instantiation within the code – that’s by design.

When you use the CompositionContainer like the example applications of WAF does then you can’t use Mefx anymore.

The alternative would be the usage of ExportFactory<T> but this is only supported for “MEF for Silverlight” at the moment.

 
Best Regards,
  jbe