IoC behavior bug?

Topics: Issues / bugs
Jun 15, 2012 at 9:47 AM
Edited Jun 15, 2012 at 9:51 AM

Hi Geert,

i'm using Unity as my primary ioc container and i register it as external container with catel (AutomaticallyKeepContainersSynchronized = true). I manually register the viewmodel services at startup with ViewModelServiceHelper.RegisterDefaultViewModelServices(). If i now try to get for example the INavigationService from the catel ServiceLocator and from the Unity container the two object instance are completely different. Is there something i'm doing wrong??

i thought that the unity container is sychronized to the "instance" of the Catel ServiceLocator....

 

Many Thanks!

Jun 15, 2012 at 9:59 AM

That should indeed be the case. do you have a small repro?

Jun 15, 2012 at 10:22 AM
Edited Jun 15, 2012 at 10:30 AM

i'm using the latest catel nightly build (3.2 beta 5) and microsoft enterprise library 5...

here's a small repro of this strange behavior...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    using System.Diagnostics;

    using Catel.MVVM;
    using Catel.MVVM.Services;

    using Microsoft.Practices.Unity;

    class Program
    {
        static void Main(string[] args)
        {
            var unityContainer = new UnityContainer();

            Catel.IoC.ServiceLocator.Instance.AutomaticallyKeepContainersSynchronized = true;
            Catel.IoC.ServiceLocator.Instance.RegisterExternalContainer(unityContainer);

            ViewModelServiceHelper.RegisterDefaultViewModelServices(Catel.IoC.ServiceLocator.Instance);

            var ns1 = unityContainer.Resolve<INavigationService>();
            var ns2 = Catel.IoC.ServiceLocator.Instance.ResolveType<INavigationService>();

            Debug.Assert(Equals(ns1, ns2), "Error");
       }
    }
}

Jun 15, 2012 at 12:14 PM

Ok, added the unit test. Here is the main description of what is happening:

1) You register item in ServiceLocator (Catel)

2) Internally, it considers itself as owning container

3) It does however, register the type in Unity as well (but not as instance, but as type, because type is not instantiated yet)

4) You retrieve value from ServiceLocator, and it considers itself as owner, and will create an instance.

 

The only solution I can think of for now is to always let the type be instantiated by the owning container as soon as synchronization kicks in.

Jun 15, 2012 at 3:03 PM

thanks a lot for the explanation and the workaround.

Jun 15, 2012 at 3:05 PM

It is implemented, we already had this implemented in case the external containers did not support type registration without instantiation. We now force instantiation.

Jun 15, 2012 at 6:22 PM

Many thanks for the fast fix. i'm looking forward to a new release....

Jun 15, 2012 at 8:10 PM

Just released a new version via NuGet. Should contain lots of fixes.

We will from now on only notify changes via twitter @CatelMvvm, not via this forum (for new releases).