StructureMap Thread Safety – Dangers of pattern chasing

Author: Stuart  //  Category: ASP.NET, MVC

Anyone who has been developing for a while will relate very much to the experience of coming up against a young developer full of ideas and the latest design patterns without understanding the background. I have half written a seperate post about the principals of design patterns which I will link to here later.

This brings me to the more immediate problem. I recently encountered a site written by a very clever developer who had probably just finished reading Scott Millet’s wonderful ASP.NET design patterns book and had rushed off to download a copy of StructureMap for his dependancy injection. Now I wasn’t there at the time, but I believe the argument was “It’s a  standard design pattern and enables unit testing..etc etc” – First mistake.

First off, the timeline never allowed for unit testing. Secondly it was as simple web form with no real business logic which makes the bet unit test to open your freakin browser and try it, and thirdly it was a highly visible, high traffic site.  NEVER try something you don’t understand in that sort of scenario, especially a community project in its infancy.

Down to the code..

The offending piece of code was in a bootstrapper that takes care of your dependancy injection concerns by instantiating classes on an application level. It means that you can refer to concrete classes anywhere in your controllers, thereby removing the perenial problem developers have with MVC.. no real underlying context.

Bootstrapper.ConfigureStructureMap();

Now in the bootstrapperregistry he had:

..
ForRequestedType<IUserRegistrationService>().TheDefaultIsConcreteType<UserRegistrationService>();
..

At first glance, nothing would appear to be wrong with this. He had service classes with instance methods that required dependancy injection and bootrapped them to the application with StructureMap. The problem is that those services then became single instances for the whole app and thereby were not thread safe. This could have easily gone unnoticed if we hadn’t tested this with multiple users on the same site at the same time. You guessed it details were being shared between users – worst nightmare for an application.

Safe ways to use bootstrapping

Personally, I don’t think there really is one. You’re hiding a lot about your classes and attaching them to a part of the http request process that’s not per request. Tempting to do this when you’re a software developer more than a web developer, but best avoided.

If you MUST bind everything somewhere so you can use it without an extra line of code, a Base controller or page would be a safer place (although it can have same problems in MVC).

My personal preference is to use Factory classes to spit out fresh little instances of your classes. For example, here’s the sort of thing I’m using in a multi database site with EF4. Would work for services too:

..
public class MyDataContextFactory
{
    public static MyDataContext1 GetMyDataContext1()
    {
        MyDataContext1 context = new MyDataContext1 (ConfigurationManager.ConnectionStrings["MyDataContext1"].ConnectionString);
        context.Database.Initialize(true);
        return context;
     }
... etc

Moral of the story

The obvious solution is to correct the usage of StructureMap, but because the developer was “pattern chasing” he came up with all sorts of explanaitions like MVC1 had thread safety issues with session (I doubt it would’ve made it to market if it did – bad implementations of view caching aside).

So the best way to improve your patterns is to start with a smaller project, build it the way you know (albeit spaghetti code) and refactor to a pattern that you understand one part at a time. Otherwise you can well go barking up the wrong tree and worst of all release massive problems into the wild on your site..

I’m also not a fan of StructureMap for this reason… and this is another reason to be careful about community projects. A commonly forgotten fact in web development is just becuase you know how to do something right, doesn’t mean the rest of your team will. Some things are just plain dangerous to leave in your code and I find it helps to try and predict the stack with a hangover.. if you get it way wrong, then you don’t know enough about your own code.

Tags: , , , ,

Leave a Reply


four − = 1