StructureMap with Named Instance and With Method

I ran into an interesting IoC issue today that was ultimately resolved by some extremely helpful email assistance by Chad Myers. I'll post the solution here in the hopes that someone else will find it helpful. Here is the code to set up the example:

public interface IFoo
{
    IBar Bar { get; set; }
}
 
public class Foo : IFoo
{
    public IBar Bar { get; set; }
 
    public Foo(IBar bar)
    {
        this.Bar = bar;
    }
}
 
public interface IBar
{
    bool Flag { get; set; }
}
 
public class Bar : IBar
{
    public bool Flag { get; set; }
 
    public Bar(bool flag)
    {
        this.Flag = flag;
    }
}

The key here is that Bar has a constructor that takes a Boolean parameter and there are some circumstances where I want Bar to have a true parameters and some instances where I want it to be false.  Because of this variability, I can't just initialize like this:

x.ForRequestedType<IBar>().TheDefault.Is.OfConcreteType<Bar>().WithCtorArg("flag").EqualTo(true);

That won't work because that only supports the "true" parameter for IBar. In order to support both, I need to utilize named instances.  Therefore, my complete StructureMapBootstrapper looks like this:

public static class StructureMapBootstrapper
{
    public static void Initialize()
    {
        ObjectFactory.Initialize(x =>
            {
                x.ForRequestedType<IFoo>().TheDefaultIsConcreteType<Foo>();
                x.ForRequestedType<IBar>().TheDefault.Is.OfConcreteType<Bar>().WithCtorArg("flag").EqualTo(true).WithName("TrueBar");
                x.ForRequestedType<IBar>().TheDefault.Is.OfConcreteType<Bar>().WithCtorArg("flag").EqualTo(false).WithName("FalseBar");
            });
    }
}

This now enables me to create instances of IBar by using the GetNamedInstance() method.  However, the primary issue is that I need to create an instance of IFoo and Foo has a nested dependency on IBar (where the parameter can vary).  It turns out the missing piece to the puzzle is to simply leverage the ObjectFactory's With() method (in conjunction with the GetNamedInstance() method) which takes an object instance and returns an ExplicitArgsExpression to enable the fluent syntax. Therefore, these instances can easily be instantiated either way like this:

var fooWithTrueBar = ObjectFactory.With(ObjectFactory.GetNamedInstance<IBar>("TrueBar")).GetInstance<IFoo>();
var fooWithFalseBar = ObjectFactory.With(ObjectFactory.GetNamedInstance<IBar>("FalseBar")).GetInstance<IFoo>();

Just another example of how IoC containers can enable us to keep clean separation of concerns in our classes and enable us to avoid cluttering our code with the wiring up of dependencies.

Tweet Post Share Update Email RSS