From the StructureMap list I saw a link to an .Net IoC tool roundup that included some mildly inaccurate comments about StructureMap (which I’ll blame on lack o’ documentation for SM 2.5, it’s on my plate, I swear!). Specifically, the author states:
With StructureMap, it was extremely hard to test it correctly, because it uses a static class for container/configuration and I had to reset it between tests.
Ok, the ReInitialize() business is a mess and needs to be documented (but you shouldn’t really ever have to use it in normal usage). However, you don’t *have* to use the static ObjectFactory and StructureMapConfiguration if you don’t want to. They’re strictly a convenience method and wrappers about two classes called Container (the actual Container) and Registry (for configuration). You can set up a Container independently of ObjectFactory by doing this:
IContainer container = new Container(registry =>
{
registry.ScanAssemblies().IncludeAssemblyContainingType<ColorWidget>();
// Add an instance with properties
registry.AddInstanceOf<IWidget>()
.UsingConcreteType<ColorWidget>()
.WithName("DarkGreen")
.WithProperty("color").EqualTo("DarkGreen");
// Add an instance by specifying the ConcreteKey
registry.AddInstanceOf<IWidget>()
.UsingConcreteType<ColorWidget>()
.WithName("Purple")
.WithProperty("color").EqualTo("Purple");
// Pull a property from the App config
registry.AddInstanceOf<IWidget>()
.UsingConcreteType<ColorWidget>()
.WithName("AppSetting")
.WithProperty("color").EqualToAppSetting("Color");
registry.AddInstanceOf<IWidget>().UsingConcreteType<AWidget>();
});
In the constructor function of Container up above takes in a single argument of Action<Registry>. In that action you simply make any or all the configuration against that Registry object being passed in. The IContainer interface has all the normal “GetInstance<T>()” type methods.
[Test]
public void AddInstanceAndOverrideTheConcreteTypeForADependency()
{
IContainer container = new Container(
registry => registry.AddInstanceOf<Rule>().UsingConcreteType<WidgetRule>()
.WithName("AWidgetRule")
.Child<IWidget>().IsConcreteType<AWidget>());
container.GetInstance<Rule>("AWidgetRule")
.IsType<WidgetRule>()
.Widget.IsType<AWidget>();
}
The author also criticizes StructureMap for not supporting the concept of hierarchical containers. StructureMap does NOT do hierarchical containers the same way as the containers that were influenced by PicoContainer & Avalon containers from Java, but there is an analogue with the “Profile” feature. I’ll get to that in the next post…
Posted
Wed, Sep 10 2008 10:30 AM
by
Jeremy D. Miller