Learning about StructureMap

December 12th, 2008

I’ve been playing around with StructureMap for the last couple of days and I must say that I’m really impressed. I had no troubles in quickly getting up to speed with this amazing IoC container. Jeremy claims that StructureMap is actually one of the first IoC containers in the .NET space. Although it has been around for a long time, somehow it has always been under (or above) my radar until my colleague Peter pointed out that I should take a look. I’ve always been a Castle Windsor fan boy, but using StructureMap for the past couple of days challenged my assumptions about IoC containers.

Anyway, I’m not going to repeat all of the good stuff that has already been written about StructureMap. Reading this post (also take a look at the linked articles) and watching these Dime Casts should get you started fairly quickly.

With this post I’m going to show you some of my personal favorite features.

1/ No explicit configuration required.

Suppose I have a simple message handler class with two dependencies. The usual Castle Windsor configuration looks like this:

 
_container.Register(
    Component.For<IUserRepository>()
    .Named("UserRepository")
        .ImplementedBy<UserRepository>(),
 
    Component.For<ILdapStore>()
     .Named("ActiveDirectory")
       .ImplementedBy<ActiveDirectory>(),
 
    Component.For<CreateUserMessageHandler>()
        .Named("CreateUserMessageHandler")
);
 
var messageHandler =  
    _container.Resolve<CreateUserMessageHandler>();

 

The StructureMap configuration for the same scenario looks like this:

 

ObjectFactory.Initialize(registry =>
{
    registry.ForRequestedType<IUserRepository>()
    .TheDefault.Is.OfConcreteType<UserRepository>();
 
    registry.ForRequestedType<ILdapStore>()
        .TheDefault.Is.OfConcreteType<ActiveDirectory>();
});
 
var messageHandler = 
    ObjectFactory.GetInstance<CreateUserMessageHandler>();

 

Notice that StructureMap doesn’t require you to register the CreateUserMessageHandler class! It’s a small detail, but a nice one.

2/ Diagnostics

If you want to provide a unit test that checks whether the configuration of the container is valid, you can use the following method :

 

ObjectFactory.AssertConfigurationIsValid();
 

If something is wrong, a StructureMapConfigurationException is thrown. It doesn’t get any easier than this.

3/ Profiles and Contextual Binding

Using profiles in StructureMap, you can basically switch container configuration based on a context. Here is a code sample that illustrates this concept:

 

ObjectFactory.Initialize(registry =>
{
    registry.CreateProfile("ActiveDirectory")
    .For<ILdapStore>().UseConcreteType<ActiveDirectory>();
    registry.CreateProfile("Fedora")
        .For<ILdapStore>().UseConcreteType<Fedora>();
});
 
ObjectFactory.Profile = "ActiveDirectory";
var ldapStore = ObjectFactory.GetInstance<ILdapStore>();
Assert.That(ldapStore, Is.TypeOf(typeof(ActiveDirectory)));
 
ObjectFactory.Profile = "Fedora";
ldapStore = ObjectFactory.GetInstance<ILdapStore>();
Assert.That(ldapStore, Is.TypeOf(typeof(Fedora)));
 

With a single line of code you can switch configuration. Again, quite easy.

4/ Custom Instance Creation

Castle Windsor provides a FactorySupport facility which enables you create your own instances for a certain type. StructureMap provides the same option through its fluent interface:

 

ObjectFactory.Initialize(registry =>
{
    registry.InstanceOf<ILdapStore>()
    .Is.ConstructedBy(() => new OpenLdap("DC=Jan,DC=BE"));
});
 
var ldapStore = ObjectFactory.GetInstance<ILdapStore>();

The fluent interface of StructureMap makes this very readable.

5/ Auto Mocking

Ayende provided an implementation of an auto mocking container in his Rhino Tools repository that uses Castle Windsor. StructureMap provides a similar API straight out of the box. No separate downloads required. You can read this article for more information. I know that there are numerous people out there who resist the idea of an auto mocking container, but it simply makes setting up mock objects and the subject-under-test less tedious.

Conclusion

As I mentioned before, I’ve been a Castle Windsor fanatic for quite some time now. The sweetness of StructureMap puts me into a mind struggle about which IoC container I like the most. To me, one of the most compelling features of Castle Windsor is its extensibility with custom facilities. I didn’t notice any equivalent feature in StructureMap. I could be wrong however, so please let me know if it does have a form of add-on capabilities. On the other hand, the ease of use and well thought out API of StructureMap makes it serious candidate as well. Anyone on my current team could start using it in no time. That’s a very important aspect as well.

Anyway, if you are looking for an IoC container, make sure to take StructureMap into account as well. Its the small subtleties in the API that makes it so nice to use.