in

 

Chad Myers' Blog

Department of Problem Prevention

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>();
Published Jul 15 2008, 09:13 PM by chadmyers
Filed under:

Comments

 

Rob G said:

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

July 16, 2008 6:05 AM
 

Jeremy D. Miller said:

The last sample could be written:

StructureMapConfiguration

   .ForRequestedType<IFoo>()

   .TheDefaultIs(

       Instance<Foo>()

           .WithProperty("NumberOfChickens")

           .EqualToAppSetting("NumChickens")

   );

for a touch more brevity

July 16, 2008 8:08 AM
 

chadmyers said:

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

@Jeremy:  Where does "Instance<Foo>" 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?

July 16, 2008 9:11 AM
 

Shane Courtrille said:

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....

July 16, 2008 9:38 AM
 

Steven Harman said:

@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.

July 16, 2008 11:30 AM
 

DotNetKicks.com said:

You've been kicked (a good thing) - Trackback from DotNetKicks.com

July 16, 2008 9:12 PM
 

Colin Jack said:

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

July 17, 2008 2:20 AM
 

David Kemp said:

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?

July 18, 2008 11:05 AM
 

chadmyers said:

@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.

July 18, 2008 11:33 AM
 

Chad Myers' Blog said:

This is a follow-on to my previous post about basic usage scenarios for StructureMap .&#160; This post

July 19, 2008 12:44 AM
 

Robert said:

"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 ;)

July 28, 2008 6:14 AM
 

chadmyers said:

@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).

July 28, 2008 9:11 AM
 

Dale Smith said:

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:

<a href="creedcultcode.blogspot.com/.../a>

August 17, 2008 2:36 PM
 

Dale Smith said:

August 17, 2008 2:49 PM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About chadmyers

Chad Myers is a senior .NET software developer specializing in enterprise software designs and architectures. He has over 10 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 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.
Copyright Los Techies 2007. All rights reserved.
Powered by Community Server (Commercial Edition), by Telligent Systems