tags:

views:

301

answers:

1

I've done quite a bit of googling and searching here on SO, but couldn't find a similar question or answer.

In typical SM configuration you can add multiple named instances for a single PluginType:

ForRequestedType<IFoo>()
  .AddInstances( x => {
      x.OfConcreteType<FooA>().WithName( "FooA" );
      x.OfConcreteType<FooB>().WithName( "FooB" );
    } );

No problem there. The problem is that I can't do the same when creating a profile. Most examples explaining how to use profiles use the For<>() method of the passed ProfileExpression:

CreateProfile( "Default", p => {
    p.For<IFoo>().UseConcreteType<FooC>();
  } );

I can't seem to find a way to add multiple named instances for the same PluginType as you can do above with regular configuration. The only other method available through ProfileExpression is Type<>(), but I'm not sure if it can be used for this purpose.

Edit: I tried to use Type<>() instead of For<>() and it seems to be taking me in the right direction, but I bumped into another problem. To better explain it here's a better example of what I'm trying to do (this is what I posted to the structuremap-users group, no answer yet):

ObjectFactory.Initialize( x => {
    x.CreateProfile( "Nissan", p =>
    {
        p.Type<ICar>().Is.OfConcreteType<NewNissanCar>().WithName( "New" );
            p.Type<ICar>().Is.OfConcreteType<OldNissanCar>().WithName( "Old" );
    } );

    x.CreateProfile( "Honda", p =>
    {
        p.Type<ICar>().Is.OfConcreteType<NewHondaCar>().WithName( "New" );
        p.Type<ICar>().Is.OfConcreteType<OldHondaCar>().WithName( "Old" );
    } );

} );

ObjectFactory.Profile = "Nissan";

ICar newCar = ObjectFactory.GetNamedInstance<ICar>( "New" ); // -> returns NewHondaCar
ICar car = ObjectFactory.GetInstance<ICar>(); // -> returns OldNissanCar

So even though I set the profile to "Nissan", GetNamedInstance<>("New") returned an instance from the incorrect profile - it should've returned NewNissanCar instead of NewHondaCar.

Interestingly, GetInstance<>() uses the correct profile, but because I can't pass an instance name, it returns an arbitrary concrete type from that profile that implements ICar (I guess it just returns the last concrete type added for that interface).

A: 

I'm not 100% sure on the syntax, but I believe this is correct:

container = new Container(x => {

    x.ForRequestedType<IFoo>()
        .AddInstances(y =>
        {
            y.OfConcreteType<FooA>().WithName("FooA");
            y.OfConcreteType<FooB>().WithName("FooB");
        });

    x.CreateProfile("Default")
        .For<IFoo>().UseNamedInstance("FooA");

});
Chris Missal
That would work if I wanted to reuse an existing named instance. Unfortunately I'd like to register a new concrete type and give it a name. After looking at the example I gave in the question I think I should've not used FooA again in the profile. I'll try to fix it to clarify my intention.
khaledh