HiveBrain v1.2.0
Get Started
← Back to all entries
snippetcsharpMinor

Create an instance (view) given its dependency (view model)

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
createviewdependencymodelinstanceitsgiven

Problem

I have a set of views and view models in my project. There is a one-to-one mapping of views and view models, so each view requires a particular view model. I'd like to instantiate a series of views given a collection of view models.

Here's what I've come up with:

public class OverlayBundle : DrawingVisual
{
    private static readonly Dictionary> _overlayCreators =
        new Dictionary>
        {
            { typeof(ImageOverlayViewModel), x => new ImageOverlay((ImageOverlayViewModel)x) },
            { typeof(ValuesOverlayViewModel), x => new ValuesOverlay((ValuesOverlayViewModel)x) },
            { typeof(NoGoAreasOverlayViewModel), x => new NoGoAreasOverlay((NoGoAreasOverlayViewModel)x) },
        };

    private readonly OverlayBundleViewModel _viewModel;

    private IEnumerable _overlays;

    public OverlayBundle(OverlayBundleViewModel viewModel)
    {
        _viewModel = viewModel;
        GenerateChildren();
    }

    private void GenerateChildren()
    {
        _overlays = _viewModel.GetAllOverlayViewModels().Select(GetOverlay);
        foreach (var overlay in _overlays)
            Children.Add(overlay);
    }

    private Visual GetOverlay(IOverlayViewModel viewModel)
    {
        return _overlayCreators[viewModel.GetType()](viewModel);
    }
}


This works, but I feel like there must be a better way. Any feedback would be appreciated.

Solution

A ViewModel should not be convertible to a View, it should be bound to it. The View should have a ViewModel property. You should not have child Views for child ViewModels. Instead, you should have one view that knows how to access the children of your top ViewModel (and there is only one of those).

The code seems way overcomplicated. Unless a Visual is a UI element like a page or control, it is probably a superfluous layer. MVVM where Views are POCO objects is usually a bad idea--it can't present to the screen, which is the most important job of a View. If I am understanding your code correctly, you could probably accomplish your goals by removing your Visual layer and converting your Bundle into a top-level ViewModel, directly binding it to your UI/View. Your child overlays should be child ViewModels of your existing ViewModels, of which there shold only be one per View, and the View knows how to access the children property of the parent ViewModel.

Context

StackExchange Code Review Q#69209, answer score: 3

Revisions (0)

No revisions yet.