Generally:
- The Model does not know about View or ViewModel.
- The View does not know about the Model, but knows about the ViewModel.
- The ViewModel does not know about the View, but knows about the Model.
How much each of these things knows about the other and how they are created, managed, and connected all depends on the layer you use to implement the MVVM abstraction itself.
Questions like:
- Who creates Views?
- Who creates ViewModels?
- Who initializes the Model?
will all depend on what MVVM framework you're using, or if you're rolling your own implementation.
For instance, in .NET + WPF, the View knows about the ViewModel by binding to properties/methods/commands by name and then setting the DataContext property of the View to an instance of the ViewModel. How you create that ViewModel is left up to you though. You might use an inversion-of-control (IOC) container to provide the instance, or you might create it yourself.
Regardless of whether or not you use a framework, there will always be some amount of code "above" the MVVM abstraction which will orchestrate data-flow and initialization.
Even if you do use a framework, you will eventually run into cases where you will need to add some additional code "above" to help "open a new Window/Dialog" or do some other application-specific thing. As long as the majority of the important stuff lives within the MVVM abstraction (so that your Models and ViewModels are fully testable without needing to create Views), and as long as you don't violate the relationships between the Model, View, and ViewModel, you'll be in a good spot. Every now and then though, it is good to review any code "above" the MVVM abstraction, and see if you can move any of it "into" the abstraction to maximize the benefits.
As a side note, you should definitely consider whether or not you need the MVVM abstraction in the first place. The primary benefits of MVVM are the ability to unit test Views and the ability to re-use ViewModels with different Views and even across entirely different projects/platforms. If you don't have these needs, you'll likely be better off simply keeping your View and Model layers separated (the Model should never know about the View, but the View can talk directly to the Model via methods/properties and can subscribe to updates). While this doesn't grant you a re-usable or testable abstraction over your Views, it still keeps your Model re-usable and testable, which is arguably the most important pattern in UI application development.
Edit:
To clarify on what I mean when I say "above" vs "inside" the MVVM abstraction. If code is "inside" the MVVM abstraction, it is correctly following all of the rules and guidelines of MVVM. If code is "above" the MVVM abstraction, it is either coordinating the abstraction in some way (ie: a Messenger
class that allows ViewModels to communicate with each other) or it outright breaks/ignores the abstraction in some way.
To give an example of some WPF code that you might write that would be considered "above":
public class App : Application
{
public static void TryCloseWindowForVM(IViewModel viewModel)
{
IView view = SomeMVVMFramework.LocateView(viewModel);
if (view is Window window)
window.Close();
}
}
Here, we provide a method on the App
class that allows ViewModels to call something like App.TryCloseWindowForVM(this)
in order to attempt to close the Window that the View this ViewModel is associated with. This will certainly throw all sorts of errors if the View and ViewModel are not associated yet, or if the View for this ViewModel is not a Window, or maybe even if there are multiple Views for this ViewModel (which can be the case in some frameworks).
This code could also be seen as rather dirty or harmful depending on what kind of rules you are willing to break. In my own experience, you'll always end up with some of this code in order to get certain things done (though sometimes there are better ways and it's always good to research first).