10

How do I get microsoft unity to 'construct' a list of classes for a given interface type.

Very Simple example:

  List<IShippingCalculation> list = new List<IShippingCalculation>();
  list.Add(new NewYorkShippingCalculation());
  list.Add(new FloridaShippingCalculation());
  list.Add(new AlaskShippingCalculation());

  //Not What I want
  public void calcship(List<IShippingCalculation> list)
  {
    var info = new ShippingInfo(list);
    info.CalculateShippingAmount(State.Alaska)
  }

  //Somehow in unity, must i do this for all the concrete classes? 
  //how does it know to give a list.
  Container.RegisterType<IShippingInfo,new AlaskaShippingCalculation()>();??

  //What I want
  public void calcship(IShippingInfo info)
  {
    info.CalculateShippingAmount(State.Alaska)
  }

Thankyou!

Ludwo
  • 6,043
  • 4
  • 32
  • 48
dnndeveloper
  • 1,631
  • 2
  • 19
  • 36

2 Answers2

14

If you are using Unity 2 you can use ResolveAll<T>

Container.RegisterType<IShippingInfo,FloridaShippingCalculation>("Florida");
Container.RegisterType<IShippingInfo,NewYorkShippingCalculation>("NewYork");
Container.RegisterType<IShippingInfo,AlaskaShippingCalculation>("Alaska");

IEnumerable<IShippingInfo> infos = Container.ResolveAll<IShippingInfo>();

You have to give a name to every registration because ResolveAll will only return named registrations.

Stephan
  • 5,430
  • 2
  • 23
  • 31
  • I guess I should say How do I do a resolve all in my constructor? or is this something I will have to make a property dependency and do a resolveall that way somehow. Thanks! – dnndeveloper Nov 17 '10 at 17:49
  • The easiest way to get it directly in your constructor will probably be to just accept the Container as a parameter and call resolve all from there. – Stephan Nov 17 '10 at 18:52
  • 4
    I would argue against using the container as a constructor argument -- classes outside your composition root should not have references to the container. See this post from Mark Seemann for more detail: http://blog.ploeh.dk/2011/07/28/CompositionRoot/ – kiprainey Oct 23 '13 at 14:25
11

You do not need to have the container as parameter, register the concrete types with names as said above, then in the constructor add a array as parameter, IList or generic Enum does not work.

public MyConstructor(IMyType[] myTypes)
Anders
  • 17,306
  • 10
  • 76
  • 144
  • Just checked this - all registered IMyType types correctly get instantiated into the array – David_001 Sep 12 '12 at 07:29
  • I have found this approach much easier to manage. All you need to do in your container is add `Container.RegisterType, IMyType[]>()` Your classes downstream don't need to know that you're using a DI framework, let alone be exposed to the details of a particular DI framework. – kiprainey Oct 23 '13 at 14:35
  • Yes to have dependency to the DI from domain classes is a antipattern. Thats why this is a much better alternative – Anders Oct 23 '13 at 14:37