PRISM creates new ViewModel by each navigation request?

284 Views Asked by At

I am using Prism v6.3.0 for a UWP app. I am using the Unity Container for DI. Following problem occurs: whenever my app navigates to a given view (e.g. MainPage) there seems that a new instance of the corresponding ViewModel is created. I would like to reuse the same VM (basically, to have it only once created).
I am having: prismMvvm:ViewModelLocator.AutoWireViewModel="True" in all of the pages' XAML.
My code never calls directly any VM constructor, so it cannot be that. I am also registering only services in the ConfigureContainer override.

What I've tried is to register the Views in App.xaml.cs (it seems to make no difference):

private void RegisterViews()
{
        Container.RegisterInstance(new LoginPage(), new ContainerControlledLifetimeManager());
        Container.RegisterInstance(new SettingsPage(), new ContainerControlledLifetimeManager());
        Container.RegisterInstance(new MainPage(), new ContainerControlledLifetimeManager());
}

Any hints?

1

There are 1 best solutions below

0
George Andras On BEST ANSWER

Since no one answered, I tried figuring out on my own once more. Now, I know that probably the best way to go about it would be to modify the container that Prism uses so it registers all the VMs as singletons. Because that sounded like too much work for this issue, I instead chose to first take a look at the ViewModelLocationProvider class. The ViewModelLocationProvider is used by PRISM to look up the VM for a given View (that has AutoWireViewModel set to true) and to inject the found VM type in the given View's DataContext.

I tried coming up with a factory for a given view that would ensure that only one VM instance would be created ever and found following solution:

protected override void ConfigureViewModelLocator()
    {
        base.ConfigureViewModelLocator();
        ViewModelLocationProvider.Register<MainPage>((delegate
        {
            var vm = Container.Resolve<MainViewModel>();
            if (Container.Registrations.All(r => r.RegisteredType != typeof(MainViewModel)))
                Container.RegisterInstance<MainViewModel>(vm, new ContainerControlledLifetimeManager());
            return vm;
        }));

        ViewModelLocationProvider.Register<SettingsPage>((delegate
        {
            var vm = Container.Resolve<SettingsViewModel>();
            if (Container.Registrations.All(r => r.RegisteredType != typeof(SettingsViewModel)))
                Container.RegisterInstance<SettingsViewModel>(vm, new ContainerControlledLifetimeManager());
            return vm;
        }));
        
    }