Search code examples
c#wpfmvvmprismdryioc

Instantiating a New View/ViewModel Instance Using Prism/MVVM


I'm new to WPF/MVVM and I'm working on a project where I've integrated Dragablz tab controls in such a way where I need the equivalent of new OEEView() to instantiate a new Window into the content area of a new tab object.

However, in the ctor of the view I'm using (OEEView), it needs a viewModel passed to it. I tried creating a new OEESelectionViewModel within the tab instantiation code and pass it to the new OEEView() but its default ctor looks like public OEESelectionViewModel(IDialogService dialogService, IOEELogger oeeLogger, ISettingsManager settingsManager) and I'm not sure how these I-objects are passed. From what I've gathered this is the responsibility of Prism and resolving dependencies using dependency injection. I've also tried creating a default(no-arg) constructor for OEEView and create a new OEESelectionViewModel within that, but I'm still stuck in terms of how to use Prism's DI.

        public OEEView(OEESelectionViewModel viewModel)
        {
            InitializeComponent();
            DataContext = viewModel;
            _viewModel = viewModel;
        }
        public OEESelectionViewModel(IDialogService dialogService, IOEELogger oeeLogger, ISettingsManager settingsManager)
        {
            ...
        }
        public TabView()
        {
            InitializeComponent();

            var tab = new HeaderedItemViewModel
            {
                Header = new HeaderWithCloseViewModel
                {
                    Header = "OEE Chart #1"
                },
                Content = new OEEView()
            };

            var viewModel = new TabViewModel(tab);

            DataContext = viewModel;
            _viewModel = viewModel;
            this.Show();
        }

I'd expect to be able to resolve a new instance and begin using it as if I used the new keyword but it isn't able to resolve itself automatically.

_container = new Container();
_container.Register<OEEView>(Reuse.Singleton);
OEEView client = _container.Resolve<OEEView>();

Additional information: Unable to resolve StationControl.ViewModels.OEESelectionViewModel as parameter "viewModel"


Solution

  • Normally, you would follow these steps:

    • ensure that your viewmodel implements an interface, i.e. IOEESelectionViewModel
    • map (register) your new interface (IOEESelectionViewModel) to a concrete type (OEESelectionViewModel) in the DI container's type registration process
    • when you create a new view, use the IOC (DI) container to resolve the interface to a concrete instance of the viewmodel

    When using PRISM, your lines of code that resolves the new concrete instance will look something like this:

    var myVM = myIocContainer.Resolve<IOEESelectionViewModel>();
    var myView = new OEEView(myVM);
    

    Of course if you wanted to be super pure you could also look to have your view resolved and created via the DI container.
    When you resolve the concrete instance of the interface, the DI container will create that instance and also auto resolve (and create) the dependencies specified in the constructor. That is part of the beauty of using a DI framework - once you've registered the mappings, magic happens. A lot of repetitive complexity is removed by using IOC patterns and a DI container.