How to setup named instances using StructureMap profiles?
- by khaledh
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).