Search code examples
.netwpfmvvmdispatchercircular-reference

How to prevent circular reference in MVVM when using DispatcherObject.Dispatcher


The below code is very simplified. I'm trying to abstract a dispatcher context so my view models can synchronize events that can only be raised on the GUI thread.

There's a circular reference in this pattern. Is there any other way to create a DispatcherObject? Am I doing it wrong?

I've read other questions like this, but the answers all seem to involve a reference to the DispatcherObject in the ViewModel. Is this an acceptable place for a circular reference?

class ViewModel {
    public DispatcherObject Dispatcher { get; set; }
}

class ModelView : UserControl {

    ModelView() {
        InitializeComponent();
        DataContext = new ViewModel { Dispatcher = this };
    }
}

Solution

  • Generally speaking, circular references are something you want to avoid. Here are two alternatives:

    1. Grab the dispatcher statically

    The quick and dirty approach. Very easy to do, will work fine almost all of the time, but as with anything else done statically it does not lend itself to testability (which may or may not be a problem). In the rare instance where your WPF app has more than one UI thread you won't be able to use this approach blindly.

    WPF: var dispatcher = Application.Current.Dispatcher;

    Silverlight: var dispatcher = Deployment.Current.Dispatcher;

    2. Make the dispatcher a dependency of the ViewModel

    Configure your dependency injection container appropriately and have the Dispatcher be a dependency for those ViewModels that need to access it. This approach is more hassle but it allows you to work with multiple UI threads, is testable, and in general has all the usual pros/cons of doing things with DI.