WPF Prism Updating ViewModel

Topics: Prism v2 - WPF 4
Jul 27, 2010 at 7:50 AM

Hi,

I am new to Prism WPF world, have one simple question.

I have registered my view and viewmodel in the module initialise method like below

        var navigatorView = new NavigationMenu.View.NavigationBarView(); 
        navigatorView
.DataContext = m_Container.Resolve<NavigationMenuViewModel>(); 
       
var regionManager = m_Container.Resolve<IRegionManager>();             
        regionManager
.Regions[RegionNames.NavigationMenuRegion].Add(navigatorView); 

Now if I want to modify my ViewModel then the only way i am able to do that is through ViewModel class only, is there any other way where I can update the viewmodel object registered with the unity container. Also i would like to know how can i get the object instance registered with the unity container.

Thanks and Regards,

Harish

Developer
Aug 3, 2010 at 6:21 PM

Hi Harish,

Before going into your questions, it’s worth noting that the most common scenario in MVVM is to have the View instantiate the ViewModel through Constructor Injection. For example, if the constructor of your NavigationBarView was like this:

 

public NavigationBarView(NavigationMenuViewModel viewModel)

{

this.DataContext=viewModel;

(…)

}

 

the container would create a new instance of your ViewModel when your View is resolved. Therefore, the code in the Initialize method of your module would look like this:

var navigatorView = m_Container.Resolve<NavigationMenu.View.NavigationBarView>(); 
var regionManager = m_Container.Resolve<IRegionManager>(); 
regionManager.Regions[RegionNames.NavigationMenuRegion].Add(navigatorView);

Now, as for your questions, when you resolve a type with the Unity Container, you don’t necessarily have to register it beforehand. As mentioned in this article, when you call the Resolve method on a type that is not registered, the container simply calls the constructor for that type and returns the result.

By registering a type in the container, you are specifying how the container creates instances of that type. For example, a type mapping ties a base class or interface to a concrete class that implements it, so that when you resolve the base class/interface an instance of the concrete class is created.

In your code, there is an example of the use of type mappings in this line:

var regionManager = m_Container.Resolve<IRegionManager>();

where you are resolving the IRegionManager interface, but obtaining an instance of the RegionManager class. This is because a type mapping was specified between them, like this:

m_Container.RegisterType<IRegionManager, RegionManager>();

With that in mind, it’s important to note that in the code you’ve shown, you haven’t registered your ViewModel in the container. If you wish to modify the ViewModel without having to alter the NavigationMenuViewModel class and recompile your application, one possibility is to create several implementations of your ViewModel and register an interface mapping in a configuration file so that you can change between them by simply editing that file.

For example, you could have something like this in your configuration file:

<register type="INavigationMenuViewModel" mapTo="SomeViewModel" />

and change it to this:

<register type="INavigationMenuViewModel" mapTo="SomeOtherViewModel" />

when you want to use another implementation.

You can read more about this in these articles from the Unity 2.0 Documentation:

As for your second question, regardless of whether you register a type or not, the container generates by default a new instance of that object each time you call the Resolve method. If you want to get the same instance every time you resolve it, you have to register the type as a singleton. Note that you should carefully consider if you need to have a type registered as a singleton, since that object will stay in memory until you close the application.

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi