Unless designated otherwise, StructureMap uses Transient as the default scope for all configured Instance's.
StructureMap's default scoping to Transient is not a universal assumption across IoC containers in .Net. Be careful with this if you are coming to StructureMap from tools that choose Singleton as their default scope.
The resolution of the lifecycle for any given Instance is to check:
- Use the explicitly configured lifecycle for the Instance
- If no lifecycle is configured for the Instance, use the explicitly configured lifecycle for the Plugin Type
- If no lifecycle is configured for either the Instance or the Plugin Type, use the default Transient lifecycle
The lifecycle precedence rules and the syntax for configuring object lifecycles are shown below:
[Fact]
public void lifecycle_precedence()
{
var container = new Container(x =>
{
x.For<IWidget>().Use<AWidget>();
// Configure the default lifecycle for
// a PluginType (Rule)
x.For<Rule>().Singleton();
x.For<Rule>().Add<ARule>().Named("C");
// Configure the lifecycle for a single Instance
x.For<Rule>().Add<ARule>().Named("A").Transient();
x.For<Rule>().Add<ARule>().Named("B").AlwaysUnique();
});
// The default lifecycle is Transient
container.Model.For<IWidget>().Default
.Lifecycle.ShouldBeOfType<TransientLifecycle>();
// Override at the Family
container.Model.For<Rule>().Lifecycle.ShouldBeOfType<SingletonLifecycle>();
container.Model.For<Rule>().Find("C").Lifecycle.ShouldBeOfType<SingletonLifecycle>();
// 'C' is the default lifecycle for Rule (SingletonThing)
container.GetInstance<Rule>("C")
.ShouldBeTheSameAs(container.GetInstance<Rule>("C"));
// 'A' is a transient
container.GetInstance<Rule>("A")
.ShouldNotBeTheSameAs(container.GetInstance<Rule>("A"));
using (var nested = container.GetNestedContainer())
{
// 'B' is always unique
nested.GetInstance<Rule>("B")
.ShouldNotBeTheSameAs(nested.GetInstance<Rule>("B"));
}
}
Using Attributes
New in StructureMap 4.0 are some simple attributes to mark either a complete Plugin Type or a single Instance as either a singleton or using the always unique lifecycle:
The usage is shown below:
[AlwaysUnique]
public interface IShouldBeUnique { }
[Singleton] // because the most wonderful thing about Tiggers is that I'm the only one....
public class Tigger { }
See Using Attributes for Configuration for information about adding your own custom attibutes for other lifecycles.