views:

360

answers:

2

I am trying to use MEF on a new project within my application. Things work at the main app level, but in this separate project whose assembly is included in the main app (its a UserControl) I am wondering about something... If I have a UserControl, and in it I have the following:

  <UserControl.Resources>
      <DataTemplate DataType="{x:Type vm:MyViewModel}" >
          <local:MyView />
      </DataTemplate>
  </UserControl.Resources>
  <vm:MyViewModel />

In my MyViewModel, I Export some stuff, and the assemblies seem to be composed just fine (Im using the CompositionInfoTextFormatter to check this). But my VM is not instantiated by MEF, or at least the constructor never gets called. And when it does get called it appears to be from the WPF framework, not MEF.

What is the right way to A) In xaml, associate my VM with its view with MEF (if different from above) and B) How do I instantiate my VM so that MEF controls it, and therefore the Exports and Imports work?

Currently they dont, which is why Im trying to make sense of this all :)

+3  A: 

Given what you're showing above, MEF doesn't come into play at all here. You have a completely self contained UserControl.

In fact, the UserControl you're showing could be done much simpler:

That's pretty much the same thing as what you wrote above. There really is no reason for this UserControl to exist, since you could just put in MyView directly.


That being said, I personally use MEF for DataTemplate generation. The way I handle it is that I have a class that exports a ResourceDictionary, and have the main application import the ResourceDictionary and merge it with the main Application Resources.

I use this export class to export a DataTemplate that maps from each View to the corresponding ViewModel. This works very well, since it allows a complete VM-first approach with no knowledge of the View from any VM.


Edit:

It sounds like your problem is that [Import]s are not being filled, since you're using WPF for construction instead of MEF. If this is the case, you'll want to use the PartInitializer class available here. For details, see Glenn Block's blog.

Reed Copsey
What I dont get is that I have exports and imports in my ViewModels, but they are not being set properly- my guess is that its because MEF is not instantiating these, WPF was. All my datatemplates are also in a ResourceDictionary in the main- but at the moment it has nothing to do with MEF. Bottom line is my import/exports arent working and I dont know why.
Nicros
Yes - Imports are only imported when MEF composes the object. If WPF is composing instead of MEF, you'll need to have the constructor handle this. Glenn Block's PartInitializer is great for this (I use it). I'll edit to answer...
Reed Copsey
@Nicros: I edited my answer to include more details.
Reed Copsey
Many thanks Reed, great info. So in the example docs frim Glenn, I see he uses the PartInitializer in his UserControl. Is this what you do as well, and then let the ResourceDictionary export the datatemplate info? So no partinitializer in the viewmodel itself is what Im getting at.
Nicros
Well, my Views are 0 code behind (other than the resource export). So I use PI in the VM, and export ResourceDictionaries for DataTemplates to handle View construction.
Reed Copsey
Would be above and beyond, but it would save me a lot of time if you could post a snippet from one of your VM constructors using the PI and show how you use the resource dictionaries. Just a request though :)For the RD my main app already contains the datatemplates. So what you are doing is pulling that RD into a separate class, exporting it so it gets composed by MEF, and then merge it with your main app? And how do you export the DataTemplates in the resource dictionary? Sorry for all the questions but this is now new territory for me :)
Nicros
@Nicros: I plan to write about this on my blog at some point soon... I need to clean up some code, but was going to show how this can be done cleanly at some point.
Reed Copsey
Looking forward to it! Thanks Reed.
Nicros
A: 

You might have a look at the sample applications of the WPF Application Framework (WAF). They show how MEF is used to instantiate the ViewModel classes.

jbe