ViewModel's constructor never execute!

Topics: Prism v4 - WPF 4
Aug 30, 2012 at 6:04 AM
Edited Aug 30, 2012 at 7:54 AM


EDIT: Let me correct the title that, VoucherViewModel's constructor only executes when Registering VoucherView.

I have a view model that belong to a View like this:

// VoucherView-ViewModel
_container.RegisterType<VoucherViewModel>(new TransientLifetimeManager());
// Constructor of VoucherViewModel executes here...
_container.RegisterType<Object, VoucherView>(VoucherViewModel.VoucherViewName, new TransientLifetimeManager(),
      new InjectionProperty(VoucherView.DataContextProperty.Name, _container.Resolve<VoucherViewModel>()));

now when i navigate to "VoucherView", VoucherViewModel's constructor never executes.
i need to display new VoucherView each time NewVoucherCommand or EditVoucherCommand execute. So VoucherViewModel implement INavigationAware like this:

    public class VoucherViewModel : NotificationObject, INavigationAware, IRegionMemberLifetime, Core.ITabContent
        // ...
        #region INavigationAware Members

        public bool IsNavigationTarget(NavigationContext navigationContext)
            // if constructor execution problem solved, uncomment lines below and remove "return false;".
            //int voucherId = 0;
            //string id = navigationContext.Parameters[VoucherIdKey];
            //if (!string.IsNullOrEmpty(id) && int.TryParse(id, out voucherId) && _voucher != null)
            //    return _voucher.Id != voucherId;
            //return true;
            return false;

        public void OnNavigatedFrom(NavigationContext navigationContext)


        public void OnNavigatedTo(NavigationContext navigationContext)
            int voucherId = 0;
            string id = navigationContext.Parameters[VoucherIdKey];
            if (!string.IsNullOrEmpty(id) && int.TryParse(id, out voucherId))
                this._voucher = _voucherRepository.Get(voucherId);
                this.IsEditMode = true;
                this.Title = string.Format("Editing Voucher Number {0}", _voucher.Number);
                this._voucher = new Voucher();
                this.VoucherNumber = _voucherRepository.GetUniqueVoucherNumber();


Result of this problem is, When i call EditVoucherCommand for id=1, A new View appears and shows VoucherId=1 data, and again when i call EditVoucherCommand for id=3, Another View appears and displays data for VoucherId=3, But previously displayed View (VoucherId=1) changes to VoucherId=3!!! I mean, VoucherView's constructor executes, but VoucherViewModel's constructor never called. It seems all VoucherView's share same instance of VoucherViewModel!!!Here it is the code for navigation:

var uriBuilder = new StringBuilder();

var uriQuery = new UriQuery();
uriQuery.Add(VoucherViewModel.VoucherIdKey, selectedVouchers.First().VoucherId.ToString());

_regionManager.RequestNavigate(RegionNames.MainRagionName, new Uri(uriBuilder.ToString(), UriKind.Relative));
Aug 30, 2012 at 8:00 AM

Hello again,

After debugging prism source code i found this line that (I think) make problem:

// RegionNavigationContentLoader.cs, method: object CreateNewRegionItem(string candidateTargetContract)
newRegionItem = this.serviceLocator.GetInstance<object>(candidateTargetContract);

after executing this line, UnityContainer should create new instance of VoucherView, and then resolve a new instance of VoucherViewModel for it's DataContext. As I say before, VoucherViewModel's constructor never called, so it seems same instance of ViewModels is shared between all VoucherViews! I dont know WHY?

Aug 30, 2012 at 4:37 PM
Edited Aug 30, 2012 at 4:40 PM


Based on my understanding, the cause of this problem is that when you register your VoucherView in the container, you are specifically passing the value to set to the DataContextProperty using the InjectionProperty class. Although, this values is resolved from the container this will only happen once, at the time of the registration, causing that each resolved instance of the view gets injected with the same instance of the VoucherViewModel.

As an alternative I believe you could try registering your VoucherView for example like this:

_container.RegisterType<Object, VoucherView>(VoucherViewModel.VoucherViewName,
 new TransientLifetimeManager(), new InjectionProperty(VoucherView.DataContextProperty.Name));

This way the value of the property will be resolved through the container, this is similar to the use of the Dependency attribute without further configuration to annotate the property.

For more information about this, I believe you could check the following MSDN article:

Also, for more information about the different approaches to use property injection with Unity, you could also check the Unity forums.

On the other hand, regarding the use of the ServiceLocator, take into account that Prism uses the service locator to abstract from the use of an specific container. In the case you mentioned the service locator will end up resolving the instance from the corresponding container, that is Unity.

For more information about the Service Locator you could check the following chapter of the Prism documentation:

I hope you find this useful,

Agustin Adami