1
votes

I am strapping up a small WPF Application with MVVM and Ninject for DI (for the first time).

Creating my "Single Instance" ViewModels for the static UI Elements is easy going. But I am struggling with the ViewModels which are created on demand, e.g. on user actions, which cannot be injected, but have to be created - somehow- in the class itself.

The easiest way would be injecting the Ninject Kernel or make it globally available, but I believe thats bad practice.

While searching for a solutions, I strumbled on these two:

  • ViewModelLocator: I think it is more for the "Single Instance" ViewModels and because I am using DataTemplates to hook up the ViewModel with the View (ViewModel first), I am feeling its not the right way, but maybe I will integrate it for my singletons (if it does make sense with using WPF DataTemplates?).

  • Factory Pattern: I read about using an Abstract Factory for Object creation and just injecting the Factory into the ViewModels, which then can use it to create the dynamic ViewModels on demand. Sounds pretty easy and thats why I am in doubt, if its just relocating the problem?

So basically I am trying to get an Instance of an ViewModel Object by the Ninject Kernel deep down in the ViewModel Tree, e.g. triggered by an user event. Because I am using an Event Broker for Ninject, the Event Broker is only hooked up for Objects created by Ninject. Thats why I need my ViewModels created/injected by Ninject.

2
So your question is what exactly? Do you need advice? The Factory Pattern is very valid!Markus Hütter
Yes, I need an advice which way to go.JDeuker
You either new InnerVM() yourself if InnerVM has not many dependencies or you InnerVMFactory.Create() it, which is cleaner. Your OuterVM will then have a dependency on InnerVMFactory.Markus Hütter
OK, thats what I imagined. And that the Factory has a dependency on the Ninject Kernel is totally valid?JDeuker
no, the factory does not have a dependency on the Ninject Kernel. The Factory does the new InnerVM(). Its dependencies are whatever Dependencies InnerVM has and it provides these to the InnerVM in every Create()Markus Hütter

2 Answers

2
votes

Go with the factory pattern. The factory itself should then be part of the composition root as Mark Seemann describes it.

To make things simple you can use Ninject.Extensions.Factory.

0
votes

We use Prism a rather big MVVM framework extensively. It is built around dependency injection and it provides a class ViewModelLocator that automatically searches for the ViewModel type that should be injected into a View when it is instantiated. Internally it uses a static service locator, but you don't need to worry about it.

<UserControl x:class=".."
    prism:ViewModelLocator.AutoWireViewModel="True">

Brian Lagunas, one of the maintainers of Prism has a nice writeup. Note that even though Prism is huge and provides loads of features you don't need to use everything.