Selecting a .NET Inversion of Control Container


03/31/2016

Selecting an inversion of control (IoC) container can be simple ("I want the one with the coolest name") or complicated ("I'm going to develop an application to measure how fast each IoC container resolves"). The Internal Services Development (ISDev) team decided to take the middle road between complicated and simple, focusing on three selection criteria:

  • Speed of dependency resolution
  • Ease of use, implementation, and maintenance
  • Product maturity and adoption rate
Speed of Dependency Resolution

There are several resources online comparing the speed of IoC containers. However the majority of them were written in 2011, which in technology terms means they are ancient and most likely irrelevant. Fortunately, we were able to find Nat's blog where he measures transient and singleton resolution times for several popular IoC containers. In our environment, the majority of our resolutions are going to be transient so we focused on the transient resolution measurements. Reviewing these numbers we selected the following IoC containers:

Selecting a .NET Inversion control container
All of these were chosen due to their performance on single transient resolves, taking into account their performance on the 1,000,000 transient resolves test. No one wants an IoC container folding under a heavy load.

Ease of Use, Implementation, and Maintenance

Having identified four IoC containers, the ISDev team investigated how easy it would be to use, implement, and maintain each IoC container. It was very difficult to find information on new(), so it was removed from selection. StructureMap, AutoFac, and Unity all had well-documented APIs that were easy to understand and implement. Each IoC, if implemented properly, would be maintainable, testable, and easy to use. However, AutoFac was removed from consideration at this point due to API preference. We felt StructureMap or Unity would fit better with our coding style. We also felt the coding style of these APIs was cleaner and more human readable, meaning any developer could jump in and quickly grasp the intent of the code and we could avoid homicidal maniacs.

Product Maturity and Adoption Rate

The remaining IoC containers, Unity and StructureMap, are mature and have high adoption rates. StructureMap has been around the longest, created back in the early days of .NET. Unity has been around since 2008, and has been featured in several MSDN articles. This criteria is a tossup between the two and we were not able to make a selection based on this criteria.

And the Winner is…

In the end, choosing an IoC container was a harder decision than we initially thought. Both IoC containers were mature, had decent resolution speeds, and were easy to use. We chose Unity due to its ease of use, implementation and maintainability and for its added features that we found useful. Unity gives us the ability to create factories for control container hydration and dependency resolution while giving the developer a very easy-to-use API for resolving their dependencies.
To use our Unity implement, the developer implements our base factory interface and overrides a method that registers and resolves their interfaces. This gives our developers a very simple pattern to follow for successfully implementing IoC without having to worry about the details.

 internal override void RegisterInterfaces()
        {
             Container .RegisterType<IProductAccess, ProductAccess>();
             Container .RegisterType<IProductLogic, ProductLogic>();
             Container .RegisterType<IProductService, ProductService>();
        }

Want more resources and insights?

Subscribe Now

Join the discussion.