I have a simple WPF application which utilizes the Unity Framework for Dependency Injection. Currently, I am trying to simplify my method for navigation between views in my MVVM pattern implementation; however, many of the examples throughout Stack Overflow do not take into consideration the Dependency Injection caveat.
I have two entirely separate views.
One, Main
acts as the main window into which content is loaded (pretty typical; unnecessary content eliminated):
<Window x:Class="Application.UI.Main">
<Grid Background="White">
<ContentControl Content="{Binding aProperty}"/>
</Grid>
</Window>
The constructor receives a ViewModel via constructor injection (again, very simple):
public partial class Main
{
private MainViewModel _mainViewModel;
public Main (MainViewModel mainViewModel)
{
InitializeComponent();
this.DataContext = _mainViewModel = mainViewModel;
}
}
I then have a UserControl
, Home
, to which I want to "navigate" the main window (i.e. set the ContentControl
. It's constructor also receives a ViewModel via constructor injection in the same way Main
does. It is equally simple:
public Home(HomeViewModel homeViewModel)
{
InitializeComponent();
// Set Data Context:
this.DataContext = homeViewModel;
}
The main problem, here, is that I want to enable constructor-based injection while maintaining as pure an MVVM implementation as possible.
I am in the View-first camp of MVVM, about which you can find a good discussion in these comments.
I have seen some allusions to the idea of a navigation based service; however, am unsure if that maintains the separation of concerns strived for by MVVM. DataTemplates
require View constructors that do not take arguments and I have read criticisms of DataTemplates that argue ViewModels should not participate in the instantiation of Views.
This solution (in my opinion) is just straight wrong as the ViewModel becomes aware of its View and relies on a service for ViewModel instantiaion which makes real Dependency Injection to resolve ViewModel and View dependencies all but impossible. This issue is very evident in the use of RelayCommand
in this MSDN article.
Does a navigation service which maintains a global, singleton-like reference to the Main
view make the most sense? Is it acceptable for the Main
view to expose a method, e.g.:
public void SetContent(UserControl userControl) { //... }
That is then accessed by that service?