ViewModel not bound to a view, used more like a Service. Is it a code smell?

51 Views Asked by At

I have a C# MVVM app (Avalonia with ReactiveUI if that matters) in which a user can create, modify and close a project. Different parts of the application need to be notified when a project is un/loaded and properly react to this.

My initial solution was to create a ProjectViewModel that I can pass around the application to leverage its property notification mechanism but it feels more like a stateful service that implements INotifyPropertyChanged than an actual ViewModel.

The ProjectViewModel has commands (to create/save/load/unload a project) and nullable properties holding data related to the project, if any. I would then pass this VM to any part of the application that needs to know about the project.

A ViewModel with a dependency on the ProjectViewModel could look like this:

public class ConfigurationExplorerViewModel
{
    private readonly ProjectViewModel _projectViewModel;

    public ConfigurationExplorerViewModel(ProjectViewModel projectViewModel)
    {
        _projectViewModel = projectViewModel;
        Configs = new();
        
        // Subscribing to when the project changes in projectViewModel.
        _projectViewModel.WhenAnyValue(x => x.Project)
            .Subscribe(RefreshProject);
    }

    private void RefreshProject(IProject? project)
    {
        Configs.Clear();

        if (project is null)
        {
            return;
        }

        foreach (var config in project.Configs)
        {
            Configs.Add(new ConfigViewModel(config));
        }
    }

    public ObservableCollection<ConfigViewModel> Configs { get; }
}

I'm starting to have doubts about this for a couple of reasons:

  1. This ViewModel is not bound to any view and feels more like a stateful service that implements INotifyPropertyChanged.
  2. Its commands could easily be moved to the MainViewModel where they would make more sense.
  3. It's only passed to other ViewModels so that they can access the Project properties and subscribe to the PropertyChanged event when it's un/loaded. For instance, a view could update to show or hide a "No Project Loaded" label.
  4. The more the application grows, the more I need to use null checks on the Project properties wherever they are needed.

I seems like I'm not separating concerns properly. Does it make sense for a ViewModel to be used this way or is it a code smell that should be addressed?

0

There are 0 best solutions below