Quite regularly I get asked by people how they should use IoC container in their application. I don’t think I can answer this question once and universally because every application is different, every application has different needs and every application has different opportunities for leveraging an Inversion of Control container.

However there are some general rules and patterns that I use and I thought I will blog about this instead.

While I use a concrete example of Castle Windsor, the discussion here is universal.It applies to all containers.

Inversion of Control means container does not exist

Basic difference between an Inversion of Control framework and any other kind of framework is that the control gets inverted. Your application does not call to the framework. Instead the framework is aware of your application and it goes and does its stuff with your application’s objects.

Since Inversion of Control Containers are Inversion of Control frameworks that paradigm applies to them as well. They control objects in your application. They instantiate them, manage their lifecycle, invoke methods on them, modify them, configure them, decorate them, do all sorts of stuff with them. The main point here is – the application is completely unaware of that. I feel tempted to put another Matrix analogy here, but hopefully you get the point without it.

The most visible manifestation of this fact, which clearly illustrates the lack of any knowledge about the container is that I tend not to reference the container in the application at all. The only place where the reference to the container does appear is the root project which only runs the application. It however contains no application logic and serves merely as application entry point and container bootstrapper.

Not referencing the container at all serves a few purposes. Most importantly it helps to enforce good OOP design, and blocks the temptation to take shortcuts and use the container as Service Locator.

Three calls pattern of usage

Now, probably the most interesting part is this simple bootstrapper. How do I interact with the container?

I tend to use pattern of three calls to the container. Yes you heard it right – I only call the container is three places in the entire application* (conditions apply, but I’ll discuss this below in just a moment).

My entire interaction with the container usually looks like this:

1: var container = BootstrapContainer();

2:

3: var finder = container.Resolve<IDuplicateFinder>();

4: var processor = container.Resolve<IArgumentsParser>();

5: Execute( args, processor, finder );

6:

7: container.Dispose();

The three steps are:

Bootstrap the container

Resolve root components

Dispose the container

Let’s go over them in turn:

One Install to rule them all…

Bootstrapping is incredibly simple:

1:private IWindsorContainer BootstrapContainer()

2: {

3:returnnew WindsorContainer()

4: .Install( FromAssembly.This() );

5: }

The most important rule here (which is important in Windsor, but good to follow with other containers that enable this) is – to call Install just once and register and configure all the components during this single call. Also important stuff is to use the Install method and Installers to encapsulate and partition registration and configuration logic. Most other containers have that capability as well. Autofac and Ninject call it modules, StructureMap calls it registries.

As you can see on the screenshot above I usually have a dedicated folder called Installers in my bootstrap assembly where I keep all my installers. I tend to partition the installers so that each one of them installs some cohesive and small set of services. So I might have ViewModelsInstaller, Controllers Installer, BackgroundServicesInstaller, LoggingInstaller etc. Each installer is simple and most of them look similar to this:

This partitioning helps keep things tidy, and by leveraging Installers you end up writing less code, as now Windsor will autodiscover them and register in just a single call to FromAssembly.This(). Also another noteworthy fact about this, is that you leverage Inversion of Control principle to configure the container itself. Instead of passing the container around, which should always raise a read flag, you’re telling Windsor – configure yourself. Nice and tidy.

Another important thing to notice, is that I tend to leverage convention based registration, rather than registering all the components one by one. This greatly cuts down the size of your registration code. It takes the burden of registering each newly added components manually off of your shoulders. It also enforces consistency in your code, because if you’re not consistent your components won’t get registered.

* yes – I do interact with the container in the installers, so I clearly break the three calls rule, right? No – I interact with the container in objects that extend, or modify the container itself – in this case it’s obviously not a bad thing.

…and in one Resolve bind them

Similar to unit tests principle – one logical assert per tests, I follow the rule of allowing explicit call to resolve in just one place in the entire application. Usually this will be just one call, that pulls the root component (Controller in MVC application, Shell in WPF application, or whatever the root object in your app is). In the example above I have two root objects so I have two calls to Resolve. That’s usually OK. However if you have more than three, you might want to take a closer look at reasons for that, as it’s quite unlikely you really need this.

The important thing is to have the Resolve calls in just this one single place and nowhere else in your application. Why that’s important? To fully leverage container’s potential, instead of telling it at every step what it should do. Let it spread its wings.

Clean up

It is important to let the container clean up after itself, when its done doing its job. In this case I can not only say that this is something I do. You also always should dispose your container at the end of your application. Always, no exceptions. This will let the container to shutdown gracefully, decommission all the components, give them chance to clean up after themselves, and free all the resources they may occupy.

Comments

Martin
wrote
re: How I use Inversion of Control containers

on 06-20-2010 4:17 PM

Thanks for this great article. This is exactly the piece of information I was always missing: how to avoid the Service Locator pattern and how to prevent referencing the container everywhere. I guess, I'm now ready to use an IOC container.

If you want to use this just to limit the lifetime scope of the components, I would not, if I was using Windsor - PerWebRequest lifestyle is the way to go here.

On the other hand, Autofac for example I think is doing just this itself.

Arild Fines
wrote
re: How I use Inversion of Control containers

on 06-21-2010 8:39 AM

But what are the patterns one should prefer if one wants to use the container to resolve components in a parameterized fashion? It's hard to avoid touching the container in that case.

For example, if you want to instantiate a view/viewmodel tuple for a, say, "Edit Customer Information" dialog. In that case, you want to parameterize on the customer, but let the container resolve everything else.

In th efirst line after the Installer code sample, you say "...and by leveraging Installers you end up writing less code, as no Windsor will autodiscover them..."

I assume you meant, "as NOW Windsor will autodiscover them"

Normally, I wouldn't bug you over a minor typo, but the error changes the meaning of the sentence.

Richard J Foster
wrote
re: How I use Inversion of Control containers

on 06-21-2010 2:29 PM

While I agree that in principle assemblies should not have any reference to the container, this isn't always as easy as might be desired. In the scenario where a specific assembly represents an optional "plug in" component requiring its own (similarly optional) Installer, what mechanism would you use?

(While it is certainly possible to add two assemblies for each plug-in, one containing the optional functionality, one containing the IoC Installer, that option feels wasteful to me. I tend to place the add-in's Installer in the same assembly, which naturally requires a reference to the IoC container. Is there a better mechanism?)

That means I logically DON"T do it unless I'm extending the container itself. I physically don't do it when I can live without it.

The scenario you're describing is one where I would likely reference Windsor in the container but not use it explicitly outside of the Installer(s)

da5id
wrote
re: How I use Inversion of Control containers

on 06-22-2010 7:41 AM

Hi,

thanks for the articel. Just one question:

From my point of view, not everything can be contained as a service in that container - especially classes that are created on the fly while working on specific tasks that also needs some services from the container . How do you handle these scenarios? Do you get the service directly from the container? Or do you wire each and every class that needs a reference to the container?

cheers

da5id

John
wrote
re: How I use Inversion of Control containers

on 06-22-2010 11:33 AM

Thanks for writing this great article. Would it be possible to provide a sample/demo application to better demonstrate this? I still have a difficult time understanding how to register components when an interface has multiple concrete classes that need to be instantiated depending on the situation.