7

I'm new to StructureMap and have some existing code that I'm working with that uses StructureMap 2.5.4.

There is a class that is constructed using StructureMap that has a constructor that takes IEnumerable<ICar> as a parameter.

The registry has the following code.

Scan(x =>
{
   x.TheCallingAssembly();
   x.WithDefaultConventions();
   x.AddAllTypesOf<ICar>();
   }
);

ForRequestedType<IEnumerable<ICar>>().TheDefault.Is.ConstructedBy(
            x => ObjectFactory.GetAllInstances<ICar>());

I'm writing a unit test and have obtained a nested container off the ObjectFactory and have injected an instance using the Inject method. One of the instances of ICar should receive the injected type in its constructor. However it wasn't working and I tracked that down to the ObjectFactory.GetAllInstances() call which doesn't use my nested container.

How can I get this to work?

I also read about StructureMap autowiring arrays and IEnumerable instances but I couldn't get it to work.

Is there a better way to rewrite the above registry code so that an instance of IEnumerable<ICar> will be created and use the injected type from my nested container?

John Mills
  • 10,020
  • 12
  • 74
  • 121

1 Answers1

7

If you are injecting an instance into a nested container, then you will need to retrieve that instance from the nested container. The static ObjectFactory has its own container, likely the 'parent' container in your case. The parent container does not inherit instances from nested containers.

You do not need to do any specific registration to have all of the instances injected into a class which accepts an IEnumerable in its constructor. StructureMap will do that automatically. If you have 3 instances of ICar registered in your container, and request an instance of Foo from that container, where Foo has an IEnumerable<ICar> constructor parameter, Foo will be created with the 3 instances of ICar injected.

Joshua Flanagan
  • 8,527
  • 2
  • 31
  • 40
  • Yes, I figured that the ObjectFactory has it's own container and so that the injected type wasn't visible to the `ObjectFactory.GetAllInstances()` call, I just need to know how to rewrite that line of code so that the injected type is visible. – John Mills Jan 12 '11 at 21:03
  • I tried removing the `ForRequestedType>().TheDefault.Is.ConstructedBy(x => ObjectFactory.GetAllInstances());` line but I get the following exception: `StructureMap Exception Code: 202 No Default Instance defined for PluginFamily IEnumerable`. From what you said, I thought that the `x.AddAllTypesOf();` line would have registered all the instances of ICar and that the IEnumerable parameter would be supplied to the constructor of the requested type. Any idea why that isn't working quite right? – John Mills Jan 12 '11 at 21:14
  • Ok, I got this working. I had to update the project to use the latest version of StructureMap. Version 2.5.4 doesn't behave the way you described, but 2.6.1 does. I also removed the `ForRequestedType>().TheDefault.Is.ConstructedBy( x => ObjectFactory.GetAllInstances());` line and was able to get the injected instance from my nested container. – John Mills Jan 13 '11 at 02:30
  • 2
    Correct. With versions before 2.6.1, StructureMap would only inject all instances if the dependency was declared in the constructor as an array (ICar[]). Recognition of IEnumerable was added in 2.6.1. – Joshua Flanagan Jan 13 '11 at 16:54