To date I’ve generally only used the most basic of StructureMap’s configuration options. Stuff like init.ForRequestedType<SomeInterface>().TheDefaultIsConcreteType<SomeImplementor>()
. But I recently needed to resolve two types which needed different configurations of the same dependency type. Here is how I got it to work, but be aware that I’m a StructureMap newbie so there might be better ways of doing this.
A contrived example
Say we have two types that both require an IController
:
public class HelloView { public HelloView(IController controller) {} } public class HowdyView { public HowdyView(IController controller) {} }
Our IController
implementation requires an IStuffDoer
:
public class Controller : IController { public Controller(IStuffDoer stuffDoer) {} }
Finally, we have two IStuffDoer
implementations:
public class SayHelloWorldDoer : IStuffDoer {} public class SayHowdyWorldDoer : IStuffDoer {}
Configuration using StructureMap
Now we want our HelloView
to have a Controller
configured with a SayHelloWorldDoer
, while our HowdyView
controller needs a SayHowdyWorldDoer
. Now this is obviously a silly, contrived example, but some semi-decent reasons to do something like this could be configuring an enumerable of Specification
instances, or passing through different pipelines to change behaviour of dependencies. For now let’s try and wire up our silly example:
public class Bootstrapper { public static void WireUpApplication() { ObjectFactory.Initialize(init => { init.ForConcreteType<HelloView>() .Configure.CtorDependency<IController>().Is( x => x.OfConcreteType<Controller>().CtorDependency<IStuffDoer>().Is<SayHelloWorldDoer>() ); init.ForConcreteType<HowdyView>() .Configure.CtorDependency<IController>().Is( x => x.OfConcreteType<Controller>().CtorDependency<IStuffDoer>().Is<SayHowdyWorldDoer>() ); } ); } }
Now when we try and resolve a HelloView
with a call to ObjectFactory.GetInstance<HelloView>()
, StructureMap will inject a Controller
configured with a SayHelloWorldDoer
for it’s IStuffDoer
.
Another way to do this is with named instances in StructureMap, but I think the approach above reads reasonably neatly and reveals our intent. It’s also worth pointing out that if our wireup logic becomes particularly complicated we may be better off moving parts of it into a factory or builder.