In which module the region manager should be located?

Apr 16, 2013 at 12:34 PM
Edited Apr 16, 2013 at 12:35 PM
What is the best practice, where the region manager should be located in views module or in view models module?

On the one hand, it seems that navigation should be controlled by view model, since the view model contains all UI logic.

On the other hand, the regions it is something that belongs to visual representation, and if we will control navigation from the view model, our view model will be coupled to region names defined in views.

Moreover, with view first approach we will need to get the view from IoC container and use this view for navigation. This means that we will need some naming conventions, to get views from IoC in view model methods, i.e. again our view model will be depend on views...

Also, I am not sure, will be view model classes unit testable if it will call the RegionManager methods?
Apr 16, 2013 at 6:47 PM

First, I believe we should make a distinction between "visual logic" and "presentation logic." Based on my understanding of the MVP pattern, the "visual logic" refers to the logic in charge of how to show the information to the user, while the "presentation logic" refers to the logic in charge of what to show to the user. Those are defined in the view and the presenter respectively. In the MVVM pattern the view model has similar responsibilities that of a presenter.

Since when injecting / navigating to a view you are deciding "what to show", I believe it's part of the "presentation" logic. So in my opinion, the RegionManager should be used in the view model.

Although regions are used to change the UI composition of the application, when you use the RegionManager in the view model you are simply adding an element to a collection or container (the region). The logic to map those elements and manipulate the UI accordingly is encapsulated in the region and is unknown by the view model. Regarding the names of the region, in WPF you can define those names in static properties of a common class that can be used in both the view model and the view (thought the x:static markup extension.) This can also be done in Silverlight 5 creating your own markup extension.

Regarding the resolution of views through the container in the view model, I believe this will depend mostly on how you use the container. First, the view model does not create or configure those views directly (the creation is performed by the container,) hence the only relation between the view model and views will be the view type. However, this can also be worked around by exporting the views through an interface or using a string to identify the view instead of the type. Once again, the view model can be completely decoupled from the views: you ask the container for an object (the view) and add that object to a collection (the region.) What's more, when using the navigation approach, the view model do not even need to obtain the instances of the views.

Finally, regarding the testability of the view model, the RegionManager implements an IRegionManager interface. By default the RegionManager is mapped to this interface in the container, so when you ask the container for an IRegionManager it returns the corresponding instance. However, during a test, you can map a different object to the IRegionManager interface (e.g. a mock region manager), allowing you to decouple the view model from the real RegionManager and test it without problems.

I hope this answer your concerns,

Damian Cherubini