tags:

views:

29

answers:

2

So I have a situation where I want to register n mappings of a particular lookup type. IE:

x.For<IWidget>().Add<SquareWidget>();
x.For<IWidget>().Add<YellowWidget>();

And I want to have SM inject an enumerable (Or array) of them into the constructor of a class:

public class Machine
{
    public Machine(IEnumerable<IWidget> widgets) { ... }
}

ObjectFactory.GetInstance<Factory>()

I'm not seeing a way to do this but I'm might be missing something.

TIA,

m

PS: Please don't respond with "why are you doing it this way" or other non relevant comments. I realize this can be accomplished using other approaches. I'm really just curious if this particular approach is possible. :)

+1  A: 

If you had an array of IWidgets in the constructor, then SM would add all IWidgets when you new a Machine, as I believe it's default behavior.

To inject a specific array:

For<IMachine>()
    .TheDefault.Is.OfConcreteType<Machine>()
    .TheArrayOf<IWidget>().Contains(
            x => {
                x.OfConcreteType<SquareWidget>();
                x.OfConcreteType<YellowWidget>();
                x.OfConcreteType<BadWidget>();
            });

or, for an IEnumerable:

For<IMachine>()
    .TheDefault.Is.OfConcreteType<Machine>()
    .CtorDependency<IEnumerable<IMachine>>().Is(i => {
        i.Is.ConstructedBy(c => {
            return new List<ITask> { 
                x.OfConcreteType<SquareWidget>();
                x.OfConcreteType<YellowWidget>();
                x.OfConcreteType<BadWidget>();
                };
             });
     });

There's probably a way to do this last one without having to be specific, but my mind balks. :)

Oh, and injection magic would be possible too.

alphadogg
alphadogg, perfect. The first example pointed me in the right direction. Thanks!
Mike OBrien
+2  A: 

With more recent versions of StructureMap (which recognize IEnumerable), it should work exactly how you have it in the question. Just register multiple concrete types using For().Add(), and then put an IEnumerable of the interface type as a constructor parameter. StructureMap will automatically inject all of the registered concrete types. No need to use specific registration code like TheArrayOf...

Joshua Flanagan
Joshua, your totally right, thanks. When I had originally tried to do it I hit an error I couldn't seem to resolve. I just went back and tried it again and dawned on me that I had one constructor overload that took IWidget and another that took IEnumerable<IWidget>. SM was trying to inject into the constructor that took IWidget but since there are two registered, and none set to be the default, SM was didn't know which one to inject into that particular constructor. So I removed the constructor that took IWidget and I was golden. Here the problem was between the chair and the keyboard... ;)
Mike OBrien