Using Inversion of Control to Sever Dependencies
Introduction
Inversion of Control is a great tool that can be used to help separate the various facets of a project. It can completely separate the knowledge of interfaces with knowledge of implementation, make the UI completely persistence-ignorant (to the point of not even referencing the Infrastructure portion of a project), and so on. In this post I will show you how to easily set up an Inversion of Control container so that you may also enjoy the pleasantries of keeping your project dependencies in check.
You can download the complete source code for this blog post both before and after IoC is introduced at the end of this post.
A Simple Super Web Application
UI’s Dependencies On Concrete Implementations
Let’s start with a sample Web Forms application that does not have any kind of inversion of control to speak of:
It is a simple setup: there is a UI project (Web Forms), a Core project for the business logic, and an Infrastructure project that handles communication with external resources (files, a database, etc).
Here is what Default.aspx looks like when run:
Let’s take a look at what the UI project currently depends on:
The code behind of Default.aspx is invoking constructors of the implementations directly. Thus, the project requires references to Infrastructure. While it is programming against an interface, the code behind is still depending directly on existing implementations of the interface. At any point these implementations could become more complex, requiring dependencies or other necessities in their constructors. It is time-consuming to have to update all usages of an implementation when it could instead rely solely on the interface definition.
Business Logic In the Wrong Place
Another problem Inversion of Control solves is the issue of having to put business logic in non-Core projects:
The SuperFactory is only in the Infrastructure project due to its default constructor knowing about an implementation that only exists in Infrastructure. This type of constructor layout is known as Poor Man’s Dependency Injection: since no Inversion of Control container exists, the class provides the default values for the constructor parameters in a parameterless constructor. However, the downside is clear. The business logic can no longer live in Core where it belongs. Instead, it has to live in Infrastructure due to its dependency on implementation.
Getting Inversion of Control Working
The IoC
It’s time now to introduce Inversion of Control to sever these dependencies and put this dependency-laden pesky project in its place. Let’s start by adding a simple static class to the root of the Core project:
This lives in Core so that any portion of the project may reference it. Notice, however, that the job of resolving the dependencies is left to the IDependencyResolver (also defined in Core), which is initialized in the given Initialize method. This action could happen in the constructor, but since this is a static class it would have to happen the instant the application started instead of the developer being in control of when initialization happens. Here’s the IDependencyResolver interface:
DependencyResolver
Now that there exists IoC, there needs to be an implementation of DependencyResolver. Here is where the actual resolution and registration of dependencies will occur. This can be done by creating a custom Inversion of Control container or using an existing one. The important thing is that the rest of the project should not know what is being used to resolve dependencies. The project only cares about using IoC to resolve an dependencies it may have. Thus, DependencyResolver will live i a new project called DependencyResolution:
In this example, Microsoft’s Unity is the Inversion of Control container of choice. Since there is a separate project, the required DLL references are only known in one place. At any point if it is decided that a different container needs to be used, it can be switched out without affecting any other portion of the project. DependencyResolver simply maintains an instance of UnityContainer and calls its Resolve and Register methods.
Registering Dependencies
Now that there exists an implementation for IDependencyResolver, there needs to be a class responsible for registering the project’s dependencies. Enter the DependencyRegistrar:
Like DependencyResolver, it also resides in the DependencyResolution project. The boolean field is to prevent extra work from happening if EnsureDependenciesRegistered is called more than once. Notice also how this uses IoC.cs to do the work of registration. Even in small projects, this file will get rather large, and breaking the registrations up into separate methods or even separate classes is usually a good idea. For now, however, it can all remain in a single method.
In order for IoC.cs to work properly in the web application, a call to EnsureDependenciesRegistered has to be made. This is accomplished in the Application_Startup method in the Global class:
Now the web forms can safely use IoC’s Resolve method to get its dependencies.
One of the benefits of Unity is that it recursively resolves dependencies, choosing the most complex constructor of the type to resolve to use to instantiate the object. For example, if the interface ISuperFactory is resolved, then ISuperFactory’s constructor exposing ISuperRepository will be called. ISuperRepository will then automatically be resolved. Due to this, there is no need for the default constructor. Now that that dependency is out of the way, SuperFactory and its business logic can now move back to Core where it belongs!
Eliminate References to Concrete Types
Let’s go ahead and replace those constructor calls in Default.aspx’s code behind with calls to IoC instead:
Now that no more implementations are being used, the UI project no longer needs to reference Infrastructure at all. Now UI only depends on Core and DependencyResolution to get the job done. The infrastructure layer can change all it wants to and the UI project will not be affected in any way. With IoC set up, does the page still render correctly? Ideally, it should look just like the picture at the beginning of this post.
Success!
Conclusion
What has been accomplished here? Any business logic that has been created or will be created can now live in Core regardless of where implementations of interfaces that it depends on live. Code that lives in Core is the easiest kind of code to test, since it by definition has no external dependencies. The interfaces can simply be mocked, faked, or stubbed and the logic itself can be thoroughly tested. Likewise, the UI project now has no business implementation details hiding away in code behind files and the like. Web Forms simply get the data they need through interface-based calls and outputs the data to the web browser. When new features are added to the project, one merely resolves an interface to start using that interface’s implementation without caring about how the interface is implemented. This makes the project incredibly flexible and free to grow.
Testing the Container
So how can one be sure that IoC is actually working correctly? Loading up the Web Forms to see is rather tedious. Furthermore, unrelated issues could crop up before being able to test IoC effectively (e.g. ASP.NET errors). In my next post I’ll show how integration testing can be used to easily prove that Inversion of Control is working properly.
Download Source
Super Web Application Before IoC
Super Web Application After IoC

Comments
Steve Smith said on 4.27.2010 at 12:25 PM
Nice writeup. I would also note that if one were using ASP.NET MVC, it wouldn't be necessary to call IOC.Resolve() within each Web Form, since these dependencies could also be injected via the constructor and a custom ControllerFactory. Likewise, I think the same could be done in web forms if a Presenter (MVP pattern) were used. I personally don't like having IOC.Resolve() in too many places.