StackOverflow open generic types

Jun 6, 2008 at 4:12 AM
I have code like

_container.RegisterType(typeof(IRepository<>), typeof(DefaultRepository<>));

later when calling _container.Resolve<IRepository<IEmployee>>();

causes a StackOverflowException.

Any ideas? I do have .net 3.5 sp1 beta installed if that makes a difference.
Jun 6, 2008 at 5:55 PM
You've GOT to give something more than just that to go on.

Can you give a COMPLETE sample that reproduces the problem? What does IRepository look like. What does DefaultRepository look like? What's IEmployee mapped to? What's the stack trace?

My guess would be circular dependencies, but without more details on the class being built up there's nothing I can do.

-Chris

Jun 6, 2008 at 7:58 PM


ctavares wrote:
You've GOT to give something more than just that to go on.

Can you give a COMPLETE sample that reproduces the problem? What does IRepository look like. What does DefaultRepository look like? What's IEmployee mapped to? What's the stack trace?

My guess would be circular dependencies, but without more details on the class being built up there's nothing I can do.

-Chris



My apologies for NOT giving you more.

Using go the go eleven framework source code found here. With the following code will reproduce the error.
IPerson is not mapped to anything in Unity.

public interface IPerson : IEntity
    {
        int PersonId { get; set; }
    }

public class Person : Entity<IPerson>, IPerson
    {
        public int PersonId
        {
            get { return Id; }
            set { Id = value; }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var container = new UnityContainer();
            container.RegisterType(typeof (IRepository<>), typeof (DefaultRepository<>));
            var personRepository = container.Resolve<IRepository<IPerson>>();
        }
    }

With the following configuration.

<configSections>
        <sectionGroup name="goeleven.framework">
            <section name="resources" type="Goeleven.Framework.Resources.ResourceConfigurationSectionHandler, Goeleven.Framework.Resources"/>
        </sectionGroup>
    </configSections>
    <goeleven.framework>
        <resources>
            <load type="Assembly" name="StackOverflowSample"/>
        </resources>
    </goeleven.framework>
Jun 7, 2008 at 5:27 PM
Here is the call stack.

    Microsoft.Practices.ObjectBuilder2.dll!Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(Microsoft.Practices.ObjectBuilder2.IBuilderContext context = {Microsoft.Practices.ObjectBuilder2.BuilderContext}) Line 37 + 0x11 bytes    C#
     Microsoft.Practices.ObjectBuilder2.dll!Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(Microsoft.Practices.ObjectBuilder2.IBuilderContext context = {Microsoft.Practices.ObjectBuilder2.BuilderContext}) Line 40 + 0xc bytes    C#
     Microsoft.Practices.ObjectBuilder2.dll!Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(Microsoft.Practices.ObjectBuilder2.IBuilderContext context = {Microsoft.Practices.ObjectBuilder2.BuilderContext}) Line 92 + 0x1f bytes    C#
     Microsoft.Practices.Unity.dll!Microsoft.Practices.Unity.ObjectBuilder.NamedTypeDependencyResolverPolicy.Resolve(Microsoft.Practices.ObjectBuilder2.IBuilderContext context = {Microsoft.Practices.ObjectBuilder2.BuilderContext}) Line 52 + 0x18 bytes    C#
     [External Code]    
     Microsoft.Practices.ObjectBuilder2.dll!Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(Microsoft.Practices.ObjectBuilder2.IBuilderContext context = {Microsoft.Practices.ObjectBuilder2.BuilderContext}) Line 37 + 0x11 bytes    C#
     Microsoft.Practices.ObjectBuilder2.dll!Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(Microsoft.Practices.ObjectBuilder2.IBuilderContext context = {Microsoft.Practices.ObjectBuilder2.BuilderContext}) Line 40 + 0xc bytes    C#
     Microsoft.Practices.ObjectBuilder2.dll!Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(Microsoft.Practices.ObjectBuilder2.IBuilderContext context = {Microsoft.Practices.ObjectBuilder2.BuilderContext}) Line 92 + 0x1f bytes    C#
     Microsoft.Practices.Unity.dll!Microsoft.Practices.Unity.ObjectBuilder.NamedTypeDependencyResolverPolicy.Resolve(Microsoft.Practices.ObjectBuilder2.IBuilderContext context = {Microsoft.Practices.ObjectBuilder2.BuilderContext}) Line 52 + 0x18 bytes    C#
Jun 7, 2008 at 11:00 PM
OK, after digging through things much more in depth. It will work if I make the default constructor use the InjectionConstructorAttribute. I originally assumed that Unity would use the default constructor when calling resolve until I noticed "Unity will use the constructor with the most parameters." in the documentation. The framework provides an additional constructor with an IRepository<T> argument as a decorator around the base ado repository. Hope this helps other lazy people such as myself. Sorry for the inconvenience.