I'm working on an application built using C# and WPF, which (badly) implements MVVM. The breakdown of work is something like:
View
- Presentation, bitmaps, colors, etc.
- Animations (if used)
- Communicates with the ViewModel by being data bound to it
- Communicates with the ViewModel by raising commands on it
ViewModel
- Exposes commands to be invoked by view(s)
- Delegates data processing functionality to the model
- Defines UI behavior
- No direct (named) dependency on the view
- Communicates with the Model by calling methods in the model
- May be notified of changes in the model by subscribing to events exposed by the model
Model
- Disk persistence, data analysis, etc
- Everything else
- No dependency on the ViewModel
Unfortunately, this has resulted in circular references, because view(s) need references to viewmodels to raise events and fire commands, viewmodels need references to views in order to update view state (typically this reference is by a viewmodel being WPF's DataContext
), viewmodels need a reference to models to delegate work, and models often need to notify viewmodels of some external change in state.
So we have two circular reference problems, with the viewmodel sitting in the middle. As a result, this application is running into memory consumption problems because WPF entities are being created and associated with some piece of data in the model, and these entities are never cleaned up (until the program is terminated).
How is this supposed to be handled?
It seems like an ownership graph needs to be defined, such that one or more of these components is responsible for disconnecting event handlers when they are no longer relevant, so that things can be GC'd.