>Lessons learned using an IoC Container

>

I am working on my first project that’s using an IoC container heavily.  Overall it’s been a very positive experience.  However, we have learned some things have caused us pain in testing, bug fixing, and general code maintenance.

Separate component registration from application start-up

This is a constant source of problem on our project.  If you don’t separate component registration from your component start-up path you often run into a chicken-and-egg problem.  You may be resolving a component that depends on other components that haven’t yet been registered.  This makes for a very brittle start-up path that is prone to breakage as you add dependencies to your components.  Now the container that is supposed to decouple things is causing you to micromanage your component registration and start-up. 

The solution is to split registration from component start-up.  This makes perfect sense to me now, but wasn’t so obvious when we started the project.  Lesson learned!

Be careful with a global service locator

We went quite a while without using a global service locator (essentially a singleton instance of the container) but eventually found that we needed it.  This might have been avoided with better design-fu but we couldn’t think of a better alternative at the time. 

What we found was that the global container made things difficult to test.  This became especially painful when we needed to push mock objects into our container and than manually clean up the registrations to replace them with the production components that other tests might expect.  I’d be interested in hearing if you have a way to solve this problem, and if so, how.

Use a Full-Featured Container

When we started the project we had intended to use Enterprise Library for some features.  EntLib has Unity integration so we settled on using Unity as our IoC container by default.  The container itself has served us extremely well.  What we’ve found lacking in the container though is it’s supporting infrastructure features.  A container like StructureMap comes with alot of nice features that aren’t core IoC features.  For example, it reduces the “ceremony” (as Jeremy D. Miller would say) of registering components by providing convention-based component registration.  StructureMap also provides detailed diagnostics that help you figure out what’s wrong with your component registrations if things don’t work.

That summarizes the biggest points that we’ve learned so far.  I’d be interested to hear some “gotchas” that you’ve learned from using an IoC container “in anger”. 

>An Introduction to StructureMap

>

Over the next several months I will be presenting a walkthrough of StructureMap.  I will be starting with the basics of how to construct objects using StructureMap and then move on to more advanced topics. 

I know there is lots of great information out there around how to use StructureMap.  My intention for writing this series is mostly selfish.  I want to learn StructureMap, and as I learn it I’ll be blogging the features I’m learning as I go. 

I’m currently working on a project that uses the Unity dependency injection container.  This container has worked very well for us, but as I’ve read various blogs and articles I’ve come to realize that a good DI container provides more than just DI.  It’s my intention to learn the basic usage of StructureMap, but also dig into the more advanced usages as well as much of it’s support infrastructure that helps you keep your dependency injection code to a minimum (thinking of auto-wiring, convention-based registration, etc).

I’ll also be updating this post as I write each new article so that this post can remain as a table of contents for the whole series.

  1. Manual component registration and resolution
  2. Auto-wiring components
  3. Convention-based registration
  4. Component lifetime management

>Beware Calculations in Unit Tests

>

Today our project’s continuous integration build failed.  I traced it down to a unit test that was exercising a scheduling class.  The class takes a schedule and figures out the next time it should run based on the current date. 

Now in our project we’ve provided a way to stub the current date or current time by having a SystemClock class that has a static Instance property.  If we need to we can push a stubbed instance into that property in a unit test to control what the current date/time is.

The problem in the unit test was that it was relying on DateTime.Now and then figuring out what the expected next scheduled time should be right in the unit test.  The calculations were wrong in the unit test and caused the unit test to fail.

Almost every time I see calculations in unit tests to figure out what the expected value should be (especially date-based calculations) I cringe because I see those as unit tests waiting to fail.  If you’ve copied your calculations from the class under test, who says you got the calculations right in the production class?  If you did the calculations differently, your unit test’s calculations could be wrong.  Wherever possible I prefer to keep the moving parts to a minimum and have constant dates as my expected values in date-based unit tests.