Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 703
Darin Dimitrov Avatar asked Nov 27 '12 09:11

Darin Dimitrov


1 Answers

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.

like image 130
Rafal Avatar answered Sep 24 '22 04:09

Rafal