Posts
208
Comments
1144
Trackbacks
51
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:

   1:  public interface IFoo
   2:  {
   3:      IBar Bar { get; set; }
   4:  }
   5:   
   6:  public class Foo : IFoo
   7:  {
   8:      public IBar Bar { get; set; }
   9:   
  10:      public Foo(IBar bar)
  11:      {
  12:          this.Bar = bar;
  13:      }
  14:  }
  15:   
  16:  public interface IBar
  17:  {
  18:      bool Flag { get; set; }
  19:  }
  20:   
  21:  public class Bar : IBar
  22:  {
  23:      public bool Flag { get; set; }
  24:   
  25:      public Bar(bool flag)
  26:      {
  27:          this.Flag = flag;
  28:      }
  29:  }

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:

   1:  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:

   1:  public static class StructureMapBootstrapper
   2:  {
   3:      public static void Initialize()
   4:      {
   5:          ObjectFactory.Initialize(x =>
   6:              {
   7:                  x.ForRequestedType<IFoo>().TheDefaultIsConcreteType<Foo>();
   8:                  x.ForRequestedType<IBar>().TheDefault.Is.OfConcreteType<Bar>().WithCtorArg("flag").EqualTo(true).WithName("TrueBar");
   9:                  x.ForRequestedType<IBar>().TheDefault.Is.OfConcreteType<Bar>().WithCtorArg("flag").EqualTo(false).WithName("FalseBar");
  10:              });
  11:      }
  12:  }

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:

   1:  var fooWithTrueBar = ObjectFactory.With(ObjectFactory.GetNamedInstance<IBar>("TrueBar")).GetInstance<IFoo>();
   2:  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.

posted on Wednesday, October 14, 2009 11:07 PM Print
Comments
Gravatar
# re: StructureMap with Named Instance and With Method
Bruce
10/15/2009 8:56 AM
Thanks Steve - I was hitting this exact issue!
Gravatar
#  StructureMap with Named Instance and With Method
True Religion jeans
10/19/2009 5:01 AM
I recently to visit your blog, reading, I very much enjoy, and above the content is great.
Gravatar
# re: StructureMap with Named Instance and With Method
Jordan 6 Rings
10/19/2009 5:02 AM
Excellent site,Thanks for this great post – I will be sure to check out your blog more often.Just subscriped to your RSS feed..
Gravatar
# re: StructureMap with Named Instance and With Method
parkster
12/29/2011 7:13 AM
Is there anywaay to instantiate the object with multiple constructor arguements?

Cheers
Simon
Gravatar
# re: StructureMap with Named Instance and With Method
Steve Michelotti
12/30/2011 12:43 PM
@parkster - sure you can just string the calls together for multiple constuctor arguments like this example shown in the SM documentation:
registry.ForRequestedType<Thing>().Use<Thing>()
.WithCtorArg("name").EqualTo("Jeremy")
.WithCtorArg("count").EqualTo(4)
.WithCtorArg("average").EqualTo(.333);

http://structuremap.net/structuremap/InstanceExpression.htm

Post Comment

Title *
Name *
Email
Comment *  
Verification

View Steve Michelotti's profile on LinkedIn

profile for Steve Michelotti at Stack Overflow, Q&A for professional and enthusiast programmers




Google My Blog

Tag Cloud