I want to start using dependency injection in my WPF application, largely for better unit testability. My app is mostly constructed along the M-V-VM pattern. I'm looking at Autofac for my IoC container, but I don't think that matters too much for this discussion.
Injecting a service into the start window seems straightforward, as I can create the container and resolve from it in App.xaml.cs.
What I'm struggling with is how I can DI ViewModels and Services into User Controls? The user controls are instantiated via XAML markup, so there's no opportunity to Resolve()
them.
The best I can think of is to place the container in a Singleton, and have the user controls resolve their ViewModels from the global container. This feels like a half-way solution, at best, as it still required my components to have a dependency on a ServiceLocator.
Is full IoC possible with WPF?
[edit] - Prism has been suggested, but even evaluating Prism seems like a big investment. I'm hoping for something smaller.
[edit] here's a code fragment where I'm stopped
//setup IoC container (in app.xaml.cs) var builder = new ContainerBuilder(); builder.Register<NewsSource>().As<INewsSource>(); builder.Register<AViewModel>().FactoryScoped(); var container = builder.Build(); // in user control ctor - // this doesn't work, where do I get the container from VM = container.Resolve<AViewModel>(); // in app.xaml.cs // this compiles, but I can't use this uc, //as the one I want in created via xaml in the primary window SomeUserControl uc = new SomeUserControl(); uc.VM = container.Resolve<AViewModel>();
MVVM – Dependency Injection. Advertisements. In this chapter, we will briefly discuss about dependency injection. We have already covered data binding decouples Views and ViewModels from each other that allows them to communicate without knowing explicitly what is going on at the other end of the communication.
NET supports the dependency injection (DI) software design pattern, which is a technique for achieving Inversion of Control (IoC) between classes and their dependencies. Dependency injection in . NET is a built-in part of the framework, along with configuration, logging, and the options pattern.
WPF is still one of the most used app frameworks in use on Windows (right behind WinForms).
Windows Presentation Foundation (WPF) provides a set of services that can be used to extend the functionality of a type's property. Collectively, these services are referred to as the WPF property system. A property that's backed by the WPF property system is known as a dependency property.
It's actually very easy to do. We have examples of this in Prism as jedidja mentioned. You can either have the ViewModel get injected with the View or the View get injected with the ViewModel. In the Prism StockTraderRI, you will see that we inject the View into the ViewModel. Essentially, what happens is that the View (and View interface) has a Model property. That property is implemented in the code-behind to set the DataContext to the value, for example: this.DataContext = value;
. In the constructor of the ViewModel, the View gets injected. It then sets View.Model = this;
which will pass itself as the DataContext.
You can also easily do the reverse and have the ViewModel injected into the View. I actually prefer this because it means that the ViewModel no longer has any back reference to the view at all. This means when unit-testing the ViewModel, you don't have a view to even Mock. Additionally, it makes the code cleaner, in that in the constructor of the View, it simply sets the DataContext to the ViewModel that was injected.
I talk a bit more about this in the video recording of the Separated Presentation Patterns talk that Jeremy Miller and I gave at Kaizenconf. The first part of which can be found here https://vimeo.com/2189854.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With