Introduction

The construction of a well-designed system is challenging, whatever its size, and the main challenges could be summarized as follows:

Objects' responsibilities

Extensibility

Reutilization

By objects' responsibilities I mean the ability of designing classes that have a clear, distinct responsibility. In other words, a class should have only one concern and the concern should be very explicit through its name and operations. It might sound trivial but any developer knows it's not. Unfortunately, this only comes with experience, and there is no shortcut.

Extensibility, however, is a polemic topic as XP enthusiasts, like myself, advocates that the extensibility exposed by an application should match the requirements brought by the client. Nothing more, nothing less.

Reuse is tricky. The more your classes depend on each other, the bigger is your headache to reuse them in different applications or different contexts. Usually, we talk in levels of linkage: is your system tight coupled or loosely coupled?

This is the first part of three articles intended to show how inversion of control might result in less code, simpler design and testable software. In this part, I'll mainly focus on what is a decoupled design and how an inversion of control container might help you. I'll also describe Castle's Windsor Container, how it works, and how to augment it.

Inversion of Control

What's inversion of control, anyway? Inversion of control is a simple principle that dictates that an external entity should send messages to programmer's objects in order to perform some specialized action or to allow the programmer to override some logic. This is the main difference between an API and a framework. On the first case, your object uses the API in an active fashion; in the second case, the framework uses your objects, so your objects are now in a passive mode.

Putting off all the hype about Inversion of Control and the wrong meaning some legends of software development try to impose to it, inversion of control is a nice design principle to construct a loosely coupled application. It requires that you shift your paradigm, though. So, before you embrace the principle, do some - or several - experimentations. It might be good to browse the code of some projects that use inversion of control too, like Cocoon, James and Turbine.

So, one of the uses of inversion of control that solves the loosely coupled problem (or one aspect of it) is by inverting how your class obtains external object references or configuration. Let's work on a not-so-distant-from-the-real-world example:

It obtains configuration from the ConfigurationSettings. What if the configuration is not there? What if you'd like to use Yaml instead of XML to hold configuration?

It instantiates a template engine. In fact, there are two problems here: one is that this class has more responsibility than the name implies. It sends an email, that's for sure, but it also uses a template engine to process the message contents. The second problem is that the class has deep knowledge about the template engine it uses. If you'd like to change the engine later, you're going to dig code.

So this simple class has two strong dependencies: the means to obtain the configuration and the template engine. Suppose you'd like to use this very class in another project. In order to do that, you'll have to:

Remember about the configuration keys.

Bring the NVelocityTemplateEngine class and all the dependencies it might have, with you.

And this is just a small class! It could be worse, and I'm positive you have seen a similar situation. Usually, the fastest solution is to copy the code and change a few things. But c'mon, there must be another way. Fortunately, there is.

Component and Services

There were people using an interesting buzzword: COP (component oriented programming). I think we already have enough of buzzwords nowadays and we should save space on our brains for more important things. Nevertheless, I'd like to depict the concepts of components.

A component is a small unit of reusable code. It should implement and expose just one service, and do it well. In practical terms, a component is a class that implements a service (interface). The interface is the contract of the service, which creates an abstraction layer so you can replace the service implementation without effort.

Better, huh? But where's the inversion of control? Before going further, allow me to make things more complex. You have probably noticed that now the email sender is only responsible for sending the email, no template processing. So let's define the contract for a template processor engine:

Let's speculate about the implementation of INewsletterService. It certainly needs to use the IEmailSender service and the ITemplateEngine service without even caring about their implementation. Fair enough, let's code:

As you can see, with small and well defined responsibilities, it's easier to cope with software development. But the problem now is that we have to assemble the application, in other words, we need to connect everything, instantiating and configuring the IEmailSender and the ITemplateEngine, pass them to INewsletterService and God knows what else. You can do it by hand, but believe me, things can get really complicated with a big system.

Castle Windsor

Castle Windsor is an inversion of control container. It's built on top of a MicroKernel responsible for inspecting the classes and trying to understand what they need in order to work and then provide the requirements or fail fast if something is wrong.

For our small example, the following code will take care of everything:

You registered the service INewsletterService on the container and you also said that the class SimpleNewsletterService contains an implementation of INewsletterService. The first argument is a key that you use to request this service later. You might also request the service by the Type.

Windsor inspected the implementation you provided and noticed that it requires two other services to work. It checked itself and realized that it doesn't have such services registered, so if somebody requests the INewsletterService service instance, it will throw an exception.

You registered the service IEmailSender. Windsor notices that the implementation has just one public constructor that receives two arguments (host and port). It's not able to satisfy this configuration as we haven't provided an external configuration. We'll fix that later.

You registered the service ITemplateEngine. Windsor registers it successfully and shouts to other components in a WaitingDependency state that a component has been registered. The INewsletterService realizes that one of its dependencies is OK to go, but it still is waiting for the other.

The fact that a class has a non default constructor has a specific meaning for the container. The constructor says to it: "Look, I really need these in order to work". If our implementation were different, the container would have used a different approach. For example:

In this case, you may or may not specify the host and port in an external configuration and the container will be able to use it. Another approach is to expose more than one constructor. The container will try to use the best constructor - meaning the one it can satisfy more arguments.

"But wait! What about the configuration?"

By default, Windsor will try to obtain the component configuration from the XML file associated with the AppDomain. However, you can override it by implementing the interface IConfigurationStore. There's another implementation of IConfigurationStore that reads the configuration from standard XML files, which is good when you have a configuration for testing environment, another for production, and so on.

From experience, I know that sometimes it's dumb to have interfaces for all your components. There are classes that are unlikely to have a different implementation, like Data Access Objects. In this case, you can register classes into the container as follows:

But please note that you can register more than one implementation for a given service. The default behavior is to return the first implementation registered for the specified service. If you want a specific implementation, then you need to use the key.

As a matter of fact, the last paragraph leads us to an interesting situation. Suppose you have implemented several IEmailSender but you want that the INewsletterService implementation uses the SMTP version and nothing else. The better way to do it is to use the configuration to specify the exact implementation you want:

Lifecycle and Lifestyle

Lifecycle and lifestyle are useful strategies that Apache Avalon have been using for quite some time (since 1999 to be exact). As a former member of Avalon, I like these ideas and decided to provide it too.

The lifestyle of a component is related to its instance. It might be singleton (which is the default lifestyle) that means that only one instance will be created for the whole life of the container. Other supported lifestyles are:

Transient: a new instance is created per request.

PerThread: just one instance exists per thread.

Custom: you provide the implementation of ILifestyleManager to implement your own semantics, like poolable objects.

There are two ways to specify the lifestyle of a component: by using attributes or by using the external configuration. In fact, the configuration overrides whatever is defined on the component. The following have the same result:

Lifecycle means the sequence of invocation that happens during the creation of your component (before making it available to the external world) and the sequence of invocation during the destruction. Out of box, Windsor only supports the IInitialize and the standard IDisposable interfaces.

More about Windsor Container

When you add a component to the container, a few things happen. First, the container creates a ComponentModel which holds a lot of meta information about the component. Then it delegates the inspection of the component to the contributors. Each contributor cares about one specific task. For example, there is a contributor that gathers all public constructors and adds to the ComponentModel, another one checks if the implementation implements specific lifecycle interfaces, another one looks for specific attributes of lifestyle, and so on.

<!--

-->

The real fun begins when you start to use this process by adding your own contributor that checks for _anything_ and gives the component a different semantic or role when found that _anything_.

There's also an important entity called Handler. The Handler is the keeper and orchestrator of the component. If the minimal set of dependencies for the component is not satisfied, the handler will not allow the component to be used (by your code or by any other component).

Now, you're ready for the most interesting section: extending the container.

Extending the Container

I'm going to present you a simple and a not so simple sample applications. The first one will introduce a different semantic to components that implement the IStartable interface; the other depicts a simple yet functional transaction infrastructure for your Data Access Objects and two ways of using it.

Basically, to extend the container, you can use a few extension points as you like. For example, you can add an inspector to look for an attribute, or an entry on the component configuration, or whatever you like. You can also subscribe to the events the MicroKernel exposes. You can even replace some parts of the MicroKernel and implement different semantics for your container (for example, to allow null values be passed to components' constructors).

When extending the container, you can give the component instance more information, register interceptors (proxies), change the lifestyle, add more lifecycles and so on. At first, let's talk about implementing a new lifecycle step.

Startable Lifecycle

Suppose you'd like that every component that implements an IStartable interface be started as soon as possible. By started, I mean:

Create an instance of it by requesting it.

Invoke the Start method defined by IStartable, so the component may start its work.

For a world usage example, imagine a WinForms application so you can register Forms subclasses as components. One component may run the Application.Run( your main form ). Thus, this component is likely to benefit from the new lifecycle. We'll use the components developed previously just to pretend we have some real action going on.

When you decide to implement extensions like that, you can do it ad-hoc, or you can create a Facility. Facility is an extension unit so you can create a library of facilities and apply them to other applications, thus reusing your work.

To implement our requirements, we need to:

Hook into the component registration process so we can inspect if the component being registered implements the IStartable interface.

So we added a contributor that looks for the IStartable interface. If found, we add a new lifecycle step which implements the ILifecycle interface. Simple, huh? But we still need to implement the logic to start the components as soon as possible. Here we go:

Now, if the component that was just registered is startable, we try to start it by requesting it. Note however that sometimes the components are not ready to be started, so we have to keep them on a list and check if they are OK to be started later.

If you'd like to see the application running, check the sample code.

A Transaction Framework for database access

In this example, the goal is to simplify the development of Data Access Objects by automatic handling of the connection and transactions. We purse two possible usages:

This Facility registers the components it needs. If the component is transactional, we associate an interceptor with it. Please note that only virtual methods can be intercepted (in future releases, we'd be able to proxy everything through interfaces).

The rest of the implementation is pretty ADO.NET specific, and I encourage you to see the sample attached to this article. Follows some screenshots of the sample implementation:

Stepping back: Castle

Castle project's goal is to offer a set of tools and an inversion of control container. The container is the rendezvous of all the tools, but this is a topic for the next article.

A few values have driven the development of the Windsor (and MicroKernel) container:

Extensibility: the container should not stop the programmer from implementing his ideas, so it must be very easy to extend it.

Orthogonality: extending the container should not impact on other extensions (as you saw).

Reversibility: the container should be able to run code that does not rely on the container API, so you can reuse your components even on other applications without using an inversion of control container.

We also don't want to be XML or configuration driven as the component holds enough information to assemble itself.

Conclusion

In the next article, I'll talk about the NHibernate and the Prevalence facilities. I'll also explain the integration with Web and the Castle on Rails MVC framework inspired by Ruby on Rails.

The Castle project still is on the alpha stage, but the public API is very unlikely to change. There is a lot of work to do, so if you enjoyed the reading, consider joining the team and help us develop tools, facilities and extensions so your next enterprise project can be done in half the time, hopefully!

History

26-Dec-2004 - Initial version.

29-Dec-2004 - Minor corrections on the text and on the sample.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

I hosted the service on console application and I am getting the error that the service type provided could not be loaded as a service because it does not have a default (parameter-less) constructor. To fix the problem, add a default constructor to the type, or pass an instance of the type to the host.

I have a service, say IssueTracker service, which implements IIssueTracker interface. It talks to NHibernate to retrieve/save data.

To make it safer, it has to be transactional. I don't want to implement the transaction in the method itself, so I use transparent proxy(Not castle proxy) and intercept the call to implement the transaction, which make my code cleaner.

The user needs to call: IssueTrackerService.CreateIssueTrackerService() to obtain an IIssueTracker interface to use.

Everything is fine. Let's say I decide to use Windsor, then I have to provide my IssueTracker as a public class, and Windsor will "new IssueTracker" to create the instance and return to the user.

This way, I lost the transaction functionality.

Of course I can use the Windsor built-in transaction facility, or implement my own interceptor, but this approach has 2 problems:

1. I am writing some code depend on Windsor (IFacility).
2. I depend on client to properly configure Windsor to use my service.

This IS a problem, as I want to make sure:
1. My service always run under a transactional environment, don't depend on any sort of configuration
2. My code is useful no matter the client use Windsor or not.

I think what I need is a way for me to provide the instance directly to windsor, or at least a way for me to control the instance creation, instead let Windsor take care of everything.

The beautiful part is: it promote an architecure that Service don't depend on each other's implementation, and my service doesn't even need to depend on Windsor!

I can easily swap out windor later on if I want to. I guess I get more of the idea than the project itself.

There're several other containers like Pico, but Iam gonna give this one a try, and see how it goes. I have to say that easy to replace helped me to make the decision to use.

Another thing is: In order to use Windsor, I have to copy 3 dlls. It's not a big deal, but it will be better to package them into one dll, include all the core facilities. A lot of developers would rather use Windsor as a blackbox.

There is a small error in the XML configuration for the "newsletter" component: the "smtpEmailSender" component is referenced with #{smtpEmailSender} but this is incorrect, at least in the beta 1 version. Correct is ${smtpEmailSender}.

Thanks, but I'm not sure what you mean. Inversion of control does not relate to ES.
The transactional facility presented here is just an example of a concern/semantic being applied to a family of components, as an example of orthogonality.

I agree. That article has too many "I"s (e.g I did this, I found out, etc.). I've read many articles on IoC containers and so far Hamilton's is the most straightforward. The example here is also very simple and general that it doesn't distract the reader from the real concepts. Fowler's writing has too many branching ideas that it's hard to get into the flow of the main topic.