StructureMap treats simple types like strings, numbers of any kind, enumerations, and dates as primitive types that are completely exempt from auto wiring -- meaning that any constructor or setter dependencies on these types must be supplied as inline dependencies.
To make this concrete, if you ask StructureMap to build a concrete type that has dependencies on simple types without like this example, StructureMap will throw an exception telling you that it cannot build the instance:
public class GuyWithNoDefaultName
{
// StructureMap will not use any kind of auto-wiring
// on name
public GuyWithNoDefaultName(string name)
{
}
}
[Fact]
public void cannot_build_simple_arguments()
{
var container = new Container();
Exception<StructureMapBuildPlanException>.ShouldBeThrownBy(() =>
{
container.GetInstance<GuyWithNoDefaultName>();
});
}
Part of the exception message thrown in the unit test shown above is the erroneous build plan
showing you that the name
parameter has to be defined:
new GuyWithNoDefaultName(String name) ┗ String name = Required primitive dependency is not explicitly defined
We can build GuyWithNoDefaultName
by supplying a value for name
as I did in the following
sample:
[Fact]
public void can_build_with_explicit_argument()
{
var container = new Container(_ =>
{
_.ForConcreteType<GuyWithNoDefaultName>()
.Configure.Ctor<string>("name").Is("Steve Winwood");
});
container.GetInstance<GuyWithNoDefaultName>()
.ShouldNotBeNull();
}
See Construction Policies for an example of using a constructor policy to set a dependency on a "connectionString" argument in a conventional way.
Default Values
As a new feature in the 4.0 release, StructureMap can finally take advantage of default parameter arguments to derive the values for a primitive argument (or setter value) while still allowing you to explicitly define that parameter or setter value:
// I was listening to Jim Croce's "I've got a Name" song
// when I wrote this feature;)
public class GuyWithName
{
public GuyWithName(string name = "Jim Croce")
{
Name = name;
}
public string Name { get; set; }
}
[Fact]
public void uses_the_default_value_if_one_exists()
{
var container = new Container();
// Should happily build with the default
// value of 'name'
container.GetInstance<GuyWithName>()
.Name.ShouldBe("Jim Croce");
}
[Fact]
public void uses_the_default_value_if_one_exists_2()
{
var container = new Container(_ =>
{
_.ForConcreteType<GuyWithName>();
});
// Should happily build with the default
// value of 'name'
container.GetInstance<GuyWithName>()
.Name.ShouldBe("Jim Croce");
}
[Fact]
public void use_explicit_dependency_if_one_exists()
{
var container = new Container(_ =>
{
_.ForConcreteType<GuyWithName>()
.Configure.Ctor<string>("name").Is("Eric Clapton");
});
container.GetInstance<GuyWithName>()
.Name.ShouldBe("Eric Clapton");
}