Importing with MEF doesn't work in non-exported ViewModels

Topics: Bootstrappers & IoC, Bugs, Framework Services, Getting Started
Apr 13, 2012 at 10:54 AM

Hello,

When I import IEventAggregator using a property in Shell, it works as expected:

public IEventAggregator Events {get;set;}  // This is imported after constructor

However, when I try to do the same in a viewmodel, it doesn't work:

public class SomeViewModel : Screen
{
    public IEventAggregator Events {get;set;}  // This doesn't get imported. WHY ?


Also notice that SomeViewModel isn't exported like Shell is. The SomeViewModel is creating in ShellViewModel just like this:

public void SomeActionInShell()
{
    ActivateItem(new SomeViewModel());
}

Is that a requirement for MEF for importing a property to work ? Or why else wouldn't this work ?

Thanks! 

Apr 13, 2012 at 11:37 AM

Actually, it appears that I'm not allowed to import anything in anywhere other that Shell. Meaning that I can only import anything (into property or constructor), but I can't Import anything in anywhere else. Any ideas why ?

Apr 13, 2012 at 1:10 PM
Composition, or rather, having your Imports satisfied only occurs when the MEF system creates the objects for you. You can ask the MEF system to run the composition on your object by having the bootstrapper bun BuildUp on your new object (or SatisfyImportsOnce from the container).

On Fri, Apr 13, 2012 at 7:38 AM, araieste <notifications@codeplex.com> wrote:

From: araieste

Actually, it appears that I'm not allowed to import anything in anywhere other that Shell. Meaning that I can only import anything (into property or constructor), but I can't Import anything in anywhere else. Any ideas

Apr 16, 2012 at 5:56 PM

First of all, you have to export your Class:

[Export(typeof(SomeViewModel)]
public class SomeViewModel : Screen

Otherwise it will not be found by MEF.

Then, you should add an [Import]-Attribute to the Property.

Finally, you can't just create an Instance of SomeViewModel as usual, because MEF has to create the Instance.
You have three Possibilities in ShellViewModel:

1) Constructor Inection -> ShellViewModel(SomeViewModel someViewModel)
2) Property Injection -> [Import] SomeViewModel _someViewModel -> ActivateItem(_someViewModel);
3) IOC -> ActivateItem(IoC.Get<SomeViewModel>())

3rd option seems to be an Anti-pattern, because you can't see from outside, that your ShellViewModel depends on SomeViewModel.
If you don't mind, you could use IoC, of course.