Error resolving a named instance using InjectionConstructor

Jan 31, 2012 at 7:01 AM
Edited Jan 31, 2012 at 9:26 AM

I have a code which look soemthing like this. The code shown below throws an error  on resolving the IServiceProvider using a default resolution. The error is " Stack over flow".. I wanted to know if the issue shown below is a known bug.  The given parameters are acceptable and both instances should be managed by Unity but it doesent seem to be happening.

  private void NamedInjectionDemo()
        {
            var uri = new Uri("http://services.odata.org/Northwind/Northwind.svc/");
            const string instanceName = "NamedInstance";
            var container = Container;
            container.RegisterType<IServiceProviderServiceProvider>(instanceName, new InjectionConstructor(uri));
            container.RegisterType<IServiceProviderServiceProvider>();
 
            var provider = container.Resolve<IServiceProvider>();
 
            LogerInstance.Logger.Write(provider);
 
            provider = container.Resolve<IServiceProvider>(instanceName);
 
            LogerInstance.Logger.Write(provider);
 
        }
internal class ServiceProvider : IServiceProvider
    {
 
        public ServiceProvider()
        {
        }
 
        public ServiceProvider(Uri uri)
        {
        }
    }
Feb 1, 2012 at 1:08 AM

I think this is a known issue.  The problem is that Unity is trying to resolve the most complicated constructor (most parameters) for ServiceProvider.  

        public ServiceProvider(Uri uri)
        {
        }

Now Unity tries to resolve Uri.  It iterates over the constructor until it hits this constructor:

      public System.Uri(System.Uri baseUri, System.String relativeUri, System.Boolean dontEscape)
      {
      }

Now Unity needs to resolve the first constructor parameter which is another Uri and the process repeats leading to infinite recursion and a StackoverflowException.

A similar issue is documented in the issue log: circular dependencies may cause stack overflow.

As I think you found out, the workaround is to configure the container to resolve the Uri class.  Or you could configure Unity to use your default constructor as the default:

            Container.RegisterType<IServiceProvider, ServiceProvider>(new InjectionConstructor());

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com