Tuesday 2 March 2010

MEFfing up a MVVM/CSLA example (Part 2)

In Part 1, we created all the necessary groundwork for a (simple) MVVM/CSLA implementation using MEF. In summary we created:

  • The Model interfaces & classes (ITelephoneList, TelephoneList and TelephoneInfo).
  • Interfaces for our View and ViewModel classes (ITelephonesView and ITelephonesViewModel).
  • A concrete ViewModel class(TelephonesViewModel).
  • A base and concrete ViewModelLocator class (ViewModelLocatorBase and TelephonesViewModelLocator respectively).
  • Imported the CompositionHost and PartInitializer classes to extend MEF support for WPF.

OK now I remember...

Lets move to the View. Add a UserControl (TelephonesView) with the following XAML:



And in the code-behind:



The view exports itself as an ITelephonesView type. When MEF resolves a new instance, a new instance of TelephonesViewModelLocator will be created. At runtime, the locator will satisfy all its imports, which includes the ViewModel of type ITelephonesViewModel, allowing the View to use it as the DataContext and access its Model (which will also be resolved by MEF by injecting the Model's factory into the ViewModel's ImportingConstructor decorated constructor).

Creating the shell

For this example, the shell will ask MEF to import a ITelephonesView part and export itself as a Shell type. The XAML:



And the codebehind:



And finally, the ViewModel of our shell:



OK I am bored now...

We are nearly there. The last thing we need to do is setup (bootstrap?) MEF. We do this in the App.xaml.cs code-behind:



If you now launch your application, MEF should setup its container and resolve a new instance of the TelephonesView, satisfying all the dependencies as described above and adding it in your Shell's StackPanel. Also, if you open TelephonesView in either Blend or the VS designer surface, you should get everything rendering just fine.

Aftermath

This example is quite a simplified one so any conclusions should be taken with a punch of salt. There are certain things that I like about this MEF approach. Defining imports/exports feels more natural than injecting instances in different classes, since the "chaining" of object creation is awesome and can be extended a lot. On the other hand, the fact that an extra base class (ViewModelLocatorBase and n ViewModelLocator classes really spoilt the picture for me. Of course, this is not a MEF shortcoming but mine, though I could not figure a way around not having the locator classes.

For now though, I don't envisage using this pattern. It will be interesting to see what the next drop of Composite WPF will bring as far as MEF is concerned and then would be a good time to revisit.