How can I resolve circular dependencies in Funq IoC? - c#

I have two classes which I need to reference each other.
class Foo
{
public Foo(IBar bar) {}
}
class Bar
{
public Bar(IFoo foo) {}
}
When I do:
container.RegisterAutoWiredAs<Foo, IFoo>();
container.RegisterAutoWiredAs<Bar, IBar>();
and when I try to resolve either interface I get a circular dependency graph which results in an infinite loop. Is there an easy way to solve this in Funq or do you know of a workaround?

You can always (and in all containers, I'd say) rely on Lazy as a dependency instead, and that would yield 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>());

The answer to your question is no, there is no easy way. Given the code above, it is impossible to construct either class without Funq, so there's no reason to expect Func to be able to do it.
var foo = new Foo(/* what do I pass here? */);
var bar = new Bar(foo);
Of course, if you had another implementation of either IFoo or IBar without the dependency, or you refactored, it might be possible.

In general, the answer to the question "how do I break up circular references when doing Dependency Injection" is: "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 this would be the way to register this dependency.
container.Register<IBar>(c =>
{
var foo = new Foo();
var bar = new Bar(foo);
foo.Bar = bar;
return bar;
});
Furthermore, I agree with Tim Rogers' comment. When you have a circular dependency, there is probably a problem in your design, and you should take a look at it. This is not always wrong, but often is. However, the code you show is very abstract, and there is no way for us to give any feedback on that.

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 without side-effects in 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;
});
p.s. but I do agree with Tim Rogers - circular reference is a problem to solve.

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()
{
}
}

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

Related

Get concrete property that implements type

Given the following classes
public Foo
{
public Foo() {
this.Bar = new Bar();
}
public IBar Bar{ get; set;}
}
public Bar : IBar
{
// implemented properties
}
How can I get the concrete implementation of the property Bar on Foo using reflection?
instance.GetType().GetProperty("Bar").PropertyType
Yields the interface only.
If you are trying to get type that implements IBar you should get it's value and take the type:
var type = instance.GetType().GetProperty("Bar").GetValue(instance,null).GetType()

How to properly use Ninject's NamedScope extension?

I have a pattern that comes up all the time when I'm working. I am almost exclusively a web developer, and Ninject's InRequestScope handles 99% of my needs.
Here's the pattern:
// abstractions
interface IFoo {
void FooMe();
int GetSomeValue();
}
interface IBar {
void BarMe();
}
interface IFooBar {
void FooAndBar();
}
// concrete classes
class Foo : IFoo {
public void FooMe() { Console.WriteLine("I have fooed"); }
public void GetSomeValue() { return 123; }
}
class Bar : IBar {
private readonly IFoo _Foo;
public Bar(IFoo foo) { _Foo = foo; }
public void BarMe() { Console.WriteLine("Bar: {0}", _Foo.GetSomeValue()); }
}
class FooBar : IFooBar {
private readonly IFoo _Foo;
private readonly IBar _Bar;
public Bar(IFoo foo, IBar bar) { _Foo = foo; _Bar = bar; }
public void FooAndBar() {
_Foo.FooMe();
_Bar.BarMe();
}
}
// bindings
kernel.Bind<IFoo>().To<Foo>();
kernel.Bind<IBar>().To<Bar>();
kernel.Bind<IFooBar>().To<FooBar>();
What I want to do is set it up such that every time I kernel.Get<IFooBar> it creates exactly one Foo and injects it into the constructors of both Bar and FooBar.
I've experimented with this off and on using the Named Scope extension, but I've never been able to get it to work.
What is the proper binding syntax for this?
so what you've got to do is define some name:
const string FooBarScopeName = "FooBarScope";
and then define the scope:
kernel.Bind<IFooBar>().To<FooBar>()
.DefinesNamedScope(FooBarScopeName);
and bind the Foo in the named scope (the name must match!):
kernel.Bind<IFoo>().To<Foo>();
.InNamedScope(FooBarScope);
Alternative:
There's also InCallScope() which can be used if there's one kernel.Get() for each time a IFooBar is created. In that case, simply do:
kernel.Bind<IFoo>().To<Foo>().InCallScope();

StructureMap - How do I use multiple objects inheriting from the same interface

When using StructureMap I would like class A to be injected with Bar and class B to be injected with Baz.
How would I configure / setup this relationship with StructureMap?
public class Bar : IFoo {}
public class Baz : IFoo {}
public class A
{
private IFoo _foo;
public A(IFoo foo)
{
_foo = foo;
}
}
public class B
{
private IFoo _foo;
public B(IFoo foo)
{
_foo = foo;
}
}
From this answer I think you need to do something like this:
For<IFoo>().Add<Bar>().Named("bar");
For<IFoo>().Add<Baz>().Named("baz");
For<A>()
.Use<A>()
.Ctor<IFoo>()
.Named("bar");
For<B>()
.Use<B>()
.Ctor<IFoo>()
.Named("baz");

Registering recursive structure with Unity container

Is it possible to register with the unity container the following recursive structure:
public interface IFoo
{
IBar[] Bars { get; set; }
}
public interface IBar
{
IFoo[] Foos { get; set; }
}
Assuming multiple named instances exist for each interface:
public class Foo1 : IFoo
{
public IBar[] Bars { get; set; }
}
public class Foo2 : IFoo
{
public IBar[] Bars { get; set; }
}
public class Bar1 : IBar
{
public IFoo[] Foos { get; set; }
}
public class Bar2 : IBar
{
public IFoo[] Foos { get; set; }
}
And the registration:
var container = new UnityContainer();
container.RegisterType<IFoo, Foo1>("foo1");
container.RegisterType<IFoo, Foo2>("foo2");
container.RegisterType<IBar, Bar1>("bar1");
container.RegisterType<IBar, Bar2>("bar2");
var instanceOfBar = container.Resolve<IBar>("bar1");
How to configure Unity container so that the collection properties are automatically injected?
There is a way to annotate a property to be a dependency. But in your case this will not work because of the infiniteness of resolution process. Simply you will get stackoverflow exception. To implement such structures I use lazy pattern so I resolve such collection only if needed:
Func<IFoo[]> resolver;
IFoo[] value;
public IFoo[] Foos { get{
if(value == null) value = resolver();
return value;
}
}
to make Func<IFoo[]> resolvable from container add this:
container.RegisterInstance<Func<IFoo[]>>(e => e.Resolve<IFoo[]>());
resolution of array or elements is done out of the box by unity it simply maps to ResolveAll.
Then simply inject Func<IFoo[]> through your constructor.
The simple answer to your question is no. Unity will regard that as a circular reference if, by resolving Foo, you instantiate one or more Bar objects which, in turn, instantiate some Foo objects.
Circular references are an issue with Unity: Circular References

Two way reference with interfaces and generics

I've got a class with generics which uses another class, which in return needs to know what instance of the initial class "owns" it - which causes problems ;) Let me give an example:
public interface IFoo<T>
{
}
public interface IBar
{
IFoo<IBar> Foo { get; set; }
}
public class Foo<T> : IFoo<T> where T : IBar, new()
{
private readonly T _bar;
public Foo()
{
_bar = new T {Foo = this};
}
}
class Bar : IBar
{
public IFoo<IBar> Foo { get; set; }
}
This doesn't work as Foo = this doesn't work - even if I try to cast this to IFoo (compiles but fails at run time). I've tried to tweak the code various ways, but I've not found an implementation that works...
Hopefully you see what I'm trying to do, and perhaps you even see how I can achieve this ;-)
You can solve this with a combination of an explicit cast in the constructor, along with c#4.0 support for covariance on generic parameters.
First, you need to insert a cast in the Foo<T> constructor:
_bar = new T {Foo = (IFoo<IBar>)this};
Just doing that isn't sufficient, though. Your constraint that T : new() means that T needs to be a concrete class. As such, IFoo<T> will never be exactly IFoo<IBar>. However, if you specify that the generic parameter T for IBar<T> is covariant, then the cast from IFoo<Bar> to IFoo<IBar> will become legal:
public interface IFoo<out T>
The out keyword specifies that the parameter is covariant (which essentially means "this parameter will only be output by methods, never input.")
This MSDN article offers more details on covariance and contravariance.
Would declaring the T type parameter of IFoo as covariant solve your problem?
This code should allow you to do what you are trying:
public interface IFoo<out T> {
}
public interface IBar {
IFoo<IBar> Foo { get; set; }
}
public class Foo<T> : IFoo<T> where T : IBar, new() {
private readonly T _bar;
public Foo() {
_bar = new T { Foo = (IFoo<IBar>)this };
}
}
class Bar : IBar {
public IFoo<IBar> Foo { get; set; }
}
public static class Program {
public static void Main(params string[] args) {
Bar b = new Bar();
Foo<Bar> f = new Foo<Bar>();
}
}

Categories

Resources