Trying to backfill a WPF application using the MVVM pattern to work with dependency injection. I'm not overly familiar with DI, having worked with it only once before, but I think I understand the principles involved.
I need to ensure that the bindings are all registered in one place - the application root. In WPF, this is the OnStartup method. So, I grabbed Ninject and threw it into my application to try and automatically bind my repository class to the initial view:
private void OnStartup(object sender, StartupEventArgs e)
{
IKernel kernel = new StandardKernel();
kernel.Bind<IRepository>().To<Repository>();
Views.MainView view = new Views.MainView();
view.DataContext = kernel.Get<ViewModels.MainViewModel>();
view.Show();
}
From hereon in, I set contexts by using a data template resource:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="clr-namespace:My.Views"
xmlns:models="clr-namespace:My.ViewModels" >
<DataTemplate DataType="{x:Type models:MyViewModel}" >
<views:MyView />
</DataTemplate>
<!-- etc -->
</ResourceDictionary>
And it works. Great! However, in MainViewModel I press a button and load a different type of ViewModel into the window:
NavigationHelper.NewWindow(this, new QuoteViewModel(quote, new Repository()));
This line of code is exactly what bought me to DI in the first place - I can't test this, because I can't mock out the dependency here. Adding DI in this instance isn't helping me at all because I'm only supposed to use my IoC container in OnStartUp, so I can't use kernel.Get to fetch my QuoteViewModel, right?
Snooping around SO I see a number of people recommending I solve this using a service locator. This is new to me, and I also see a number of people telling me that using this for DI is an anti-pattern which shouldn't be touched with a bargepole. Who's right?
And perhaps more importantly, is there a neat solution to this issue? I've seen a couple of other examples that demand a smorgasbord of different packages to make it work. Right now, it feels like MVVM and DI just aren't made to play nice with each other.