views:

53

answers:

1

I'm trying to configure alternate constructor arguments when a requested type is being injected into several classes. In previous StructureMap versions, it would look a lot like the very first DSL example on the document page, but I'm having trouble figuring out how to configure it with the new syntax.

What I've got now is an one interface with one concrete implementation, but I'm needing the constructor arguments to change based on the object it is being injected into. For example:

interface IInterface{}
class Concrete : IInterface
{
  public Concrete(string param) {}
}
class ConsumerOne
{
  public ConsumerOne(IInterface i) {} // Concrete(param) to be "One"
}
class ConsumerTwo
{
  public ConsumerTwo(IInterface i) {} // Concrete(param) to be "Two"
}

class MyRegistry : Registry
{
  public MyRegistry()
  {
    For<IInterface>()
      .Use<Concrete>
      .Ctor<string>("param")
      .Is(/* "One" if being injected into ConsumerOne,
             "Two" if being injected into ConsumerTwo */);
   }
}

I'm thinking I can maybe do this with .AddInstance(x => {}), after the For<IInterface>(), but I'm having trouble discovering how to do this. Any help or advice would be appreciated!

+1  A: 

Using named instances you can accomplish this like so:

For<IInterface>().Use<Concrete>().Named("1")
    .Ctor<string>("param").Is("One");
For<IInterface>().Use<Concrete>().Named("2")
    .Ctor<string>("param").Is("Two");

For<ConsumerOne>().Use<ConsumerOne>()
    .Ctor<IInterface>().Is(x => x.GetInstance<IInterface>("1"));
For<ConsumerTwo>().Use<ConsumerTwo>()
    .Ctor<IInterface>().Is(x => x.GetInstance<IInterface>("2"));

A potential drawback to this is that you need to add an entry for each new type of ConsumerX that you add.

Chris Missal
You should use Add instead of Use for the IInterface registrations, since it's not a default you're registering. The potential drawback could be resolved by creating a Convention.
PHeiberg