StructureMap: Basic Scenario Usage

First, I’m going to assume that you are somewhat already familiar with the concepts of Dependency Injection and what, in general, an Inversion of Control Container is for. If not, you may find these links helpful:

 

I’m also going to assume that you know what I’m talking about when I say “StructureMap”.  If not, then you should check out this link:

 

If I’ve lost you with any of these assumptions, please leave a comment and I’ll step back and go into these some more for you!

Most Common Usages

I’m going to cover three of the more common usage scenarios and how you accomplish these with the upcoming StructureMap 2.5.

Simple Factory

I have an interface IFoo with a concrete implementation Foo. When IFoo is requested, new up and return a Foo.

First, somewhere in the startup code area of your application, register the two types with the container, like so:

StructureMapConfiguration
    .ForRequestedType<IFoo>()
    .TheDefaultIsConcreteType<Foo>();

Next, to retrieve the instance elsewhere in your code, use the ObjectFactory class in StructureMap:

// fooInstance is actually of type Foo
IFoo fooInstance = ObjectFactory.GetInstance<IFoo>();

 

Object Lifetime Manager

I have a session-type object I need kept alive for the entire thread or ASP.NET request.  When IFoo is requested, return me a Foo instance specific to this ASP.NET request or thread

StructureMap can create an instance of an object for you and manage it’s life time according to the life of the current Thread or, in an ASP.NET scenario, the life of the current HTTP request.  This is useful for caching things like database connection sessions or user credentials, etc.

First, when you define your object in your startup code, add the CacheBy() option:

StructureMapConfiguration
    .ForRequestedType<IFoo>()
    .TheDefaultIsConcreteType<Foo>()
    .CacheBy(InstanceScope.HttpContext);

You can also use InstanceScope.ThreadLocal for non-ASP.NET multithreaded scenarios, InstanceScope.Singleton which means the object will live for the entire life of your AppDomain, and InstanceScope.Hybrid which will choose HttpContext if available, otherwise it’ll revert to ThreadLocal. Hybrid is particularly handy in a unit testing scenario where your tests will automatically adapt to either a live ASP.NET scenario or a test threading scenario.

Then, request your object just like normal:

IFoo fooInstance = ObjectFactory.GetInstance<IFoo>();

If you’ve called GetInstance<IFoo> more than once in that same ASP.NET request, you’ll get the same Foo instance.  If there are two requests executing simultaneously on your web server, they’ll each get their own Foo instance.

 

Object Assembler

I have an object that needs to have a value set from the application configuration on startup. When IFoo is requested, new up a Foo, set it’s NumberOfChickens property from the AppSettings/NumChickens setting in my app.config and return me the instance.

UPDATE 7/26/2008:  My apologies — at the time of this post and updating, StructureMap does not currently set property values unless they have the [SetterProperty] attribute.  The ‘WithProperty’ and ‘SetProperty’ methods are misleading as they apply normally to CONSTRUCTOR parameters by that name OR properties with the [SetterProperty] attribute placed upon them.  There have been several requests for this in the past and there is likelihood the ability to set properties without requiring attributes will be added to the final StructureMap 2.5 release (currently version is 2.4.9).

Like the previous examples, define your object in your startup code, but change it slightly to have StructureMap automatically take care of getting the property for you:

StructureMapConfiguration
    .ForRequestedType<IFoo>()
    .TheDefaultIs(
        new ConfiguredInstance()
            .UsingConcreteType<Foo>()
            .WithProperty("NumberOfChickens")
            .EqualToAppSetting("NumChickens")
    );

Just like the others, the business end is still the same:

IFoo fooInstance = ObjectFactory.GetInstance<IFoo>();

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Chad Myers

Chad Myers is the Director of Development for Dovetail Software, in Austin, TX, where he leads a premiere software team building complex enterprise software products. Chad is a .NET software developer specializing in enterprise software designs and architectures. He has over 12 years of software development experience and a proven track record of Agile, test-driven project leadership using both Microsoft and open source tools. He is a community leader who speaks at the Austin .NET User's Group, the ADNUG Code Camp, and participates in various development communities and open source projects.
This entry was posted in StructureMap. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://www.eisolutions.co.uk Rob G

    Hey Chad,

    Good post – I really hope this might turn into a series? For example, it might be good to see common (best practice) usages when combining StructureMap with Mocks – InjectStub springs to mind here. There are so many ways to skin a Rhino/Moq these days – deciding what is best practice can be tough!…and time consuming.

    cheers
    Rob

  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    The last sample could be written:

    StructureMapConfiguration
    .ForRequestedType()
    .TheDefaultIs(
    Instance()
    .WithProperty(“NumberOfChickens”)
    .EqualToAppSetting(“NumChickens”)
    );

    for a touch more brevity

  • http://chadmyers.lostechies.com Chad Myers

    @Rob: I was planning a few more posts, so please stay tuned.

    @Jeremy: Where does “Instance” come from? That appears to only be valid when you’re in a class that derives from Registry or RegistryExpressions. What if you’re just in Program.cs or Global.asax.cs?

  • http://shane.jscconsulting.ca Shane Courtrille

    Thanks for this. I’ve been playing with 2.5 a lot and loving it but the lack of simple documentation has been a bit… frustrating :)

    I’m actually using it exactly how you point out though so I guess in the end I did get it figured out pretty good. Now if only I could figure out how I got it to stack overflow….

  • http://stevenharman.net Steven Harman

    @Shane,
    Your stack overflow is likely caused by a circular dependency between two (or more) of the classes that StructureMap is trying to wire up.

  • http://colinjack.blogspot.com Colin Jack

    Excellent stuff, I’m just getting started with StructureMap (been a Castle man up till now) so this sort of content is great.

  • David Kemp

    The last example -> with version 2.4.9, this seems to only do constructor injection and not property injection (as the name would suggest)? Is this correct?

  • http://chadmyers.lostechies.com Chad Myers

    @David:

    StructureMap *CAN* do property injection either via attributed properties ([SetterProperty] or something like that, I forget the exact attribute) or via the .WithProperty() stuff in the examples above.

    However, I’d like to strongly discourage you from doing property injection. There are a few scenarios where the debate still rages (some cross-cutting concerns, optional dependencies, etc) but by and large, property injection should be discouraged.

  • Robert

    “StructureMap can create an instance of an object for you and manage it’s life time according to the life of the current Thread or, in an ASP.NET scenario, the life of the current HTTP request. This is useful for caching things like database connection sessions or user credentials, etc.”

    Shouldn’t there be a .CacheBy(InstanceScope.HttpSession) in the case of user credentials? Most sites don’t make you log in for every request ;)

  • http://chadmyers.lostechies.com Chad Myers

    @Robert: Good point.

    I actually meant something like the Principal object or anything that you might need to know about the user. Some of these things happen every request (think FormsAuthentication and HttpModules, etc).

  • http://creedcultcode.blogspot.com Dale Smith

    Hey Chad,

    I swiped some code from Josh and cobbled together my own little StructureMap sample app, but I used StructureMap 2.0 instead of the 2.4.9 preview. If you want to have a look you can see it here:

    http://creedcultcode.blogspot.com/2008/08/boba-fett-greedo-and-structuremap.html

  • http://creedcultcode.blogspot.com Dale Smith