How can I resolve circular dependencies in Funq IoC?

I have two classes that I need to relate to each other.

class Foo { public Foo(IBar bar) {} } class Bar { public Bar(IFoo foo) {} } 

When I do this:

 container.RegisterAutoWiredAs<Foo, IFoo>(); container.RegisterAutoWiredAs<Bar, IBar>(); 

and when I try to resolve any interface, I get a circular dependency graph that leads to an infinite loop. Is there an easy way to solve this problem in Funq, or do you know about a workaround?

+4
source share
6 answers

You can always (and in all containers, I would say) rely on Lazy as a dependency, and this will give the desired result. In Funq:

 public Bar(Lazy<IFoo> foo) ... public Foo(Lazy<IBar> bar) ... container.Register<IBar>(c => new Bar(c.LazyResolve<IFoo>()); container.Register<IFoo>(c => new Foo(c.LazyResolve<IBar>()); 
+6
source

In general, the answer to the question "how to break circular links when performing dependency injection": "use property injection".

 class Foo { public Foo() {} // Break the dependency cycle by promoting IBar to a property. public IBar Bar { get; set; } } class Bar { public Bar(IFoo foo) {} } 

With Funq, I think it will be a way to register this dependency.

 container.Register<IBar>(c => { var foo = new Foo(); var bar = new Bar(foo); foo.Bar = bar; return bar; }); 

Also, I agree with Tim Rogers comment. When you have circular addiction, perhaps there is a problem in your design and you should take a look at it. This is not always wrong, but it often happens. However, the code you show is very abstract, and we cannot give you any feedback.

+2
source

The answer to your question is no, there is no easy way. Given the above code, it's impossible to build any class without Funq, so there is no reason to expect Func to be able to do this.

 var foo = new Foo(/* what do I pass here? */); var bar = new Bar(foo); 

Of course, if you had a different implementation of either IFoo or IBar without dependency, or you were reorganized, perhaps this is possible.

+1
source

This works for me:

 using Funq; using NUnit.Framework; namespace FunqIoCyclicReferenceTest { [TestFixture] public class FunqIoCCyclicReferenceTest { [Test] public void Please_Work() { var container = new Container(); container.Register<IBar>(c => new Bar()); container.Register<IFoo>(c => new Foo(c.Resolve<IBar>())); var foo = container.Resolve<IFoo>(); Assert.IsNotNull(foo); } } public class Foo : IFoo { public Foo(IBar bar) { bar.Foo = this; Bar = bar; } public IBar Bar { get; set; } } public interface IBar { IFoo Foo { get; set; } } public interface IFoo { IBar Bar { get; set; } } public class Bar : IBar { public IFoo Foo { get; set; } } } 

EDIT
Same idea, but no side effects in the constructor:

 // interfaces public interface IBar { IFoo Foo { get; set; } } public interface IFoo { IBar Bar { get; set; } } // implementations public class Foo : IFoo { public IBar Bar { get; set; } } public class Bar : IBar { public IFoo Foo { get; set; } } // usage container.Register<IBar>(c => new Bar()); container.Register<IFoo>(c => { var bar = c.Resolve<IBar>(); var foo = new Foo(); bar.Foo = foo; foo.Bar = bar; }); 

ps but I agree with Tim Rogers - a circular link is a problem to solve.

0
source

After registering your types in the container, make the container available as a static variable:

 public static class ContainerHolder { public static Container Container {get;set;} } public class Foo : IFoo { private IBar _bar; public Foo(IBar bar) { _bar = bar; } } public class Bar : IBar { private IFoo _foo { get { return ContainerHolder.Container.Resolve<IFoo>(); } } public Bar() { } } 
0
source

I had a similar scenario, and the dependency between the two classes made me realize that they should be combined into one class.

0
source

Source: https://habr.com/ru/post/1432728/


All Articles