Prism can create an unneeded ViewModel if you have a one-arg constructor on your view. I am trying to understand how this can be avoided, or, if I can design something to work differently. Here is what happens.
The XAML view declares ViewModelLocator.AutoWireViewModel:
mvvm:ViewModelLocator.AutoWireViewModel="True"
And the class declares two constructors:
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
}
public MainWindow(MainWindowViewModel viewModel)
{
InitializeComponent();
DataContext = viewModel;
}
}
There is a reason that I declare the one-arg constructor: it is because the ViewModel is serializable; and when deserialized, the view is constructed by explicitly invoking that constructor with the restored ViewModel. But the issue can happen in two ways.
First, when you invoke the one-arg constructor:
MainWindowViewModel viewModel = new MainWindowViewModel();
MainWindow window = new MainWindow(viewModel);
Then Prism constructs the view, and that invokes the ViewModelLocator from the XAML, which creates and sets a ViewModel ... And then your explicit argument is set; replacing the auto-created instance (or if you reverse the lines in the constructor, than your explicit argument is actually wiped off).
AND, perhaps unexpectedly, or perhaps by some folly in my understanding, or some other unknown design aspect, it ALSO will happen if you resolve the view from the Container --- you might do this expecting to invoke the default constructor for the view; but that in fact does not happen; and, once again you will create two ViewModels:
MainWindow window = Container.Resolve<MainWindow>();
This line of code actually begins by discovering the one-arg constructor on the View, and then RESOLVING a ViewModel and invoking that constructor ... which again triggers the XAML auto-ViewModel; and then your one-arg constructor continues to wipe off the auto-ViewModel ...
It's consuming resources; and in fact, I tripped an exception where the view was binding based on some other state that was inconsistent with the ViewModel that I was expecting to explicitly be set.
I can't see a way to defeat the auto-created instance, and so I am not seeing how to invoke a one-arg constructor around the AutoWireViewModel behavior; or, how to resolve the view from the Container and avoid two ViewModels being created.
Perhaps resolving the View from the Container is abuse if it hasn't been registered, but the one-arg constructor seems to be reasonable, and it creates two instances ...
Is there some way? [Perhaps you can customize that behavior to check for an existing DataContext and then not set it if present ... or something along those lines?]
I created a simple example on GitHub: