Dependency Injection and Single Responsibility Principle in MVVM

when dealing with DI and Constructor Injection, you have a useful indicator of SRP violations, because the number of constructor parameters will increase to the number that we start to feel uncomfortable with. One solves this by refactoring into reasonably adapted classes and using facade services and similar approaches.

However, when it comes to MVVM and the view model in particular, I find it difficult to apply these rules. The view model, by its very nature, is responsible for providing commands that, when invoked, execute some of the UI logic and invoke the business layer. I don't want to start a discussion about where to place the business logic, let's agree on this in separate classes.

Now imagine a simple scenario: Weve have a file listing window. The user can add files, delete files, and do something with them like renaming and opening a folder. The window also collects and displays some metadata for files in list columns asynchronously. In addition, the user can open the parts view and launch the online help. All this can be done from the toolbar and context menu. Ok lets stop here with functionality. One straight forward way to cluster could be as follows:

  • ViewModel (for the whole window, command implementation for the mentioned functionality)

View model dependencies:

  • FileManipulation
  • WindowsExplorerService (To open an explorer window to show the contained folder)
  • OnlineHelp
  • MetadataGatherer
  • MessageService (To open message boxes to show errors and like)
  • DetailsService (Provides a user interface for displaying information for known file formats)

It's already 6 dependencies and it's easy to bump up the number by adding functionality that can be launched from the toolbar. In my opinion, dependencies cannot be hidden behind sensible facade services, since each of them covers completely different functionality (well, we can argue about the metadata of the Gatherer and FileManipulation).

I think view models are special in the sense that they encapsulate the redirection of user actions to very different dependencies. However, 6 or more dependencies make me feel uncomfortable and the corresponding constructor smells bad. Am I missing an important point? Any ideas on how to refactor such a case at all?

+3


source to share


1 answer


The solution here is to use composition. The main window should be a composite element, each with its own view model, and this view model will handle a single responsibility. The master model model will organize them. They can communicate with each other using the event bus. Almost all popular MVVM frameworks are supported (I know about Caliburn Micro and ReactiveUI).



+4


source







All Articles