Use the technique shown here with caution.
If you need to add or change configuration to an existing StructureMap Container
object, you can use the IContainer.Configure()
method
to add or change your container at runtime as shown below:
[Fact]
public void change_default_in_an_existing_container()
{
var container = new Container(x => { x.For<IFoo>().Use<AFoo>(); });
container.GetInstance<IFoo>().ShouldBeOfType<AFoo>();
// Now, change the container configuration
container.Configure(x => x.For<IFoo>().Use<BFoo>());
// The default of IFoo is now different
container.GetInstance<IFoo>().ShouldBeOfType<BFoo>();
// or use the Inject method that's just syntactical
// sugar for replacing the default of one type at a time
container.Inject<IFoo>(new CFoo());
container.GetInstance<IFoo>().ShouldBeOfType<CFoo>();
}
Best Practices
First off, the best advice on this functionality is don't use it outside of testing scenarios on the root container. The Configure()
method has to use a threading lock around the internal object model of a StructureMap container and can cause serious contention at runtime if you try to override services in the main application controller. Some frameworks (looking at you NancyFx) have abused this functionality quite badly in the past and the result was not pretty.
- Do favor writing configuration to StructureMap
Registry
objects, then applying thatRegistry
to a container rather than repeatedly callingConfigure()
- Do not call
Configure()
on the main application container after the initial configuration. Use nested or child containers that are not shared across threads or HTTP requests if you need to override services at runtime - There's a potential performance hit from using
Configure()
at runtime because StructureMap has to recycle its internal Build Plan's based on the potential new configuration.