How can I combine MVVM and Dependency Injection in a WPF app?

15,317

Solution 1

If a view model can only exist in conjunction with another, I create a strong relationship. That is the owning view model will have a direct reference to one or more of the dependent view models. If, on the other hand, a view model should be able to exist with or without another, I take a loosely-coupled approach where they communicate via an event bus.

In terms of using DI with MVVM, absolutely you can combine the two. It's as simple as:

public class MyViewModel
{
    private readonly IMyDependency _myDependency;

    public MyViewModel(IMyDependency myDependency)
    {
        _myDependency = myDependency;
    }
}

Note, however, that this assumes a "view model first" approach to MVVM, which has its drawbacks.

Solution 2

In WPF it's normally pretty easy and it doesn't really depend on any particular DI Container. Have you read Josh Smith's article on MVVM? It pretty much describes how to set up a hierarchy of ViewModels.

What it doesn't go into much is how to create those ViewModels from dependencies (such as Repositories), but it's not a difficult extrapolation to do.

I've often experienced that liberal use of Abstract Factories helps quite a lot in this regard. Instead of directly new'ing up ViewModels I let an injected Factory do it for me.

You can use Poor Man's DI or any kind of DI Container to wire up such Factories for you.

Solution 3

I published this article on Code Project about how to make an extensible WPF app using MVVM and MEF for extensibility. However, if you look closely, I used MEF for DI as well.

The application is fully MVVM and only uses DataTemplates (and the occasional Window) for Views, just like in Josh Smith's article. WPF takes care of applying the correct View to the right ViewModel for you. It's sweet.

It uses MEF so that the parts can "find" each other. So the ViewModel for the "View" menu item finds all the menu items that are supposed to be in the submenu using extension points, and the ViewModels for each of those "find" the ViewModel they're supposed to hand to the layout manager using composition points. They also "find" the layout manager service using a rudimentary service locator (MEF). The View menu example is almost precisely what you're talking about with nested ViewModels. The cool thing is they don't even know about each other until runtime.

Share:
15,317

Related videos on Youtube

Max Galkin
Author by

Max Galkin

Blog: http://yacoder.guru/blog/ Twitter: @yacoder My CV: http://careers.stackoverflow.com/yacoder

Updated on April 17, 2022

Comments

  • Max Galkin
    Max Galkin about 2 years

    Can you please give an example of how you would use (your favorite) DI framework to wire MVVM View Models for a WPF app?

    Will you create a strongly-connected hierarchy of View Models (like where every nested control's ViewModel is a property on a parent's ViewModel and you bind it to nested control's DataContext in XAML) or you would use some kind of even-more-abstract ""View Model" Manager", which maintains some weakly-connected hierarchy... like in CAB, maybe?

  • Mark Seemann
    Mark Seemann over 14 years
    I have to say that I'm not a big fan of 'active' ViewModels... It's hard to come up with a one-sentence rational argument for this, but I think I am in the 'ViewModels should be passive' camp...
  • Max Galkin
    Max Galkin over 14 years
    Surely I've read the article, but it doesn't go into details on creating and maintaining a larger set of ViewModels with several dependencies in each one. I'm afraid your answer is not useful for me (
  • Max Galkin
    Max Galkin over 14 years
    What do you mean by 'active'/'passive' View Model, Mark?
  • Mark Seemann
    Mark Seemann over 14 years
    @Yacoder: Kent Boogaart's example is an 'active' ViewModel because it takes a dependency, and one must assume that it intents to use that dependency in an active way. A 'passive' ViewModel, on the other hand, is one you create and fill with data, and once you've done that, it's self-contained.
  • Mark Seemann
    Mark Seemann over 14 years
    @Yacoder: You'd be surprised how many people use the MVVM term here on StackOverflow without having read the article.
  • aroon65
    aroon65 over 14 years
    This is also known as view-model-first versus view-first. I prefer VM-first but understand that it doesn't play well with Blend. To each his own, I guess.
  • nlawalker
    nlawalker over 13 years
    I think I understand view-first vs. viewmodel-first but I'm afraid I don't understand this answer or the comments very well - how do ViewModel dependencies, in the constructor or anywhere else, imply a viewmodel-first approach? The dependency in the example in the answer could be filled by a container. @Mark, I don't understand what you mean - are you implying a ViewModel shouldn't have any dependencies? How would you "fill it with data" if it's disconnected/isolated and doesn't have any dependencies? Thanks!
  • Mark Seemann
    Mark Seemann over 13 years
    To be honest I've changed my viewpoint a bit in the last 8 months. I'd prefer passive ViewModels, but in MVVM it works better with active ViewModels. In ASP.NET MVC, OTOH, passive ViewModels are much easier to wrangle because we can use Controllers to fill them. Different contexts require different solutions...
  • Thomas
    Thomas over 8 years
    @KentBoogaart sorry to try and get your attention this way; can you look at this question