Search code examples
c#ioc-containerdryioc

DryIoc recursive dependency exception with Factory (Func<>)


Hey I've switched over to DryIoc from Autofac. My code previously worked but now causes an exception "Recursive dependency is detected when resolving". (Code is simplified)

public class AFactory {
   public AFactory(Func<A> getA){ }
}

public class BFactory {
   public BFactory(Func<B> getB, AFactory factory){ }
}

public class A { 
   public A(IrrelevantService service, BFactory factory){ }
}

The actual code is complicated so assume that there is a reason that this code structure is necessary.

It's trying to resolve AFactory --> A --> BFactory --> AFactory and this is causing the issue. But since it's using a Func<> so it should be fine? (or at least it is in Autofac).

Is there a way to register this so that it doesn't throw this exception?


Solution

  • Here is the reason from the Func wrapper docs:

    By default, does not permit recursive dependency.

    The fix is described in the doc below or in the later section.

    Here are all possible fixes:

    using System;
    using DryIoc;
                        
    public class Program
    {
        public static void Main()
        {
            var c = new Container(
                //rules => rules.WithFuncAndLazyWithoutRegistration() // fix1: make everything lazy resolvable preventing the recursive dependency check!
            );
            
            c.Register<A>(
                //setup: Setup.With(asResolutionCall: true) // fix2: makes A a dynamically resolvable
            );
            c.Register<AFactory>();
            
            c.Register<B>();
            c.Register<BFactory>(
                setup: Setup.With(asResolutionCall: true) // fix3: makes BFactory a dynamically resolvable - the fix is here and not in B because the BFactory is already loops to AFactory and making B dynamic is not enough
            );
            
            c.Register<IrrelevantService>();
            
            var af = c.Resolve<AFactory>();
            Console.WriteLine(af);
        }
        
        public class AFactory {
           public AFactory(Func<A> getA){ }
        }
    
        public class BFactory {
           public BFactory(Func<B> getB, AFactory aFactory){ }
        }
    
        public class A { 
           public A(IrrelevantService service, BFactory bFactory){ }
        }
        
        public class B {}
        public class IrrelevantService {}
    }