17

I want to do a simple resolve of multiple type registrations (ultimately constructor injected, but using .Resolve to see if Unity is even capable of such things.

In every case below, Unity resolves 0 items where it should be resolving 2.

Is there some switch in unity that turns on post-2007 behavior? Or am I just drastically missing something?

Here is my code:

public interface IFoo {}
public class Foo1 : IFoo{}
public class Foo2 : IFoo{}

class Program
{
    static void Main(string[] args)
    {
        var container = new UnityContainer();
        container.RegisterType<IFoo, Foo1>();
        container.RegisterType<IFoo, Foo2>();

        // container.Resolve<IEnumerable<IFoo>>();   returns 0
        // container.ResolveAll<IFoo>(); returns 0

        var foos = container.Resolve<IFoo[]>();
        Console.WriteLine(foos.Count());

        Console.ReadLine();

    }
}
ChrisBint
  • 12,773
  • 6
  • 40
  • 62
S. Hebert
  • 808
  • 1
  • 8
  • 18

1 Answers1

35

In Unity there can only be one default registration (A registration without a name as in container.RegisterType<IFoo, Foo1>(); ). If multiple default registrations are performed, the last one wins.

In order to register multiple implementation for the same interface, you need to assign names to those registrations:

container.RegisterType<IFoo, Foo1>("registration1");
container.RegisterType<IFoo, Foo2>("registration2");

Also, Unity only understand arrays by default. If you want to resolve as an array then you will be fine with the default behaviour. Otherwise you will need to register a mapping between the array and the collection you are interested in, like:

container.RegisterType<IEnumerable<IFoo>, IFoo[]>();

Another important note is that the default registration won't be returned when resolving a collection. For example given:

container.RegisterType<IFoo, Foo1>();
container.RegisterType<IFoo, Foo2>("registration1");
container.RegisterType<IFoo, Foo3>("registration2");
container.RegisterType<IEnumerable<IFoo>, IFoo[]>();

If you resolve IEnumerable<IFoo>, the result will only contain instances of Foo2 and Foo3, but there will not be an instance of Foo1 because the default registration is not included.

Daniel J.G.
  • 34,266
  • 9
  • 112
  • 112
  • In an MVC app, is it ok to do `var container = new UnityContainer();` and `container.Resolve()` wherever I want it? Or is there a better way to do it? – Narayana Jan 06 '14 at 06:42
  • 3
    @Narayana You should leave that to a single place in your application known as the composition root. In MVC you usually have some kind of bootstrapper that creates the container and use it with a custom `DependencyResolver` or `ControllerFactory`. The rest of your code should just declare its dependencies via constructor/dependency injection. Take a look at [this article](http://www.asp.net/mvc/tutorials/hands-on-labs/aspnet-mvc-4-dependency-injection). – Daniel J.G. Jan 06 '14 at 09:23
  • doesn't bring back the default registration, that is tad weird imho. live and learn. – granadaCoder Apr 11 '17 at 15:14