Using the StructureMap Container independently of ObjectFactory

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…

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.
This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.