Dependency Injection and Inversion of Control with ASP.NET MVC

As you delve more into ASP.NET MVC you start to come across a whole new way of doing things that Web Forms development didn't really expose you to. Inversion of Control (IoC) and Dependency Injection (DI) are two phrases that crop up a lot in the MVC space. So what are they all about? And should you care?

I should start by stating the IoC and DI are not unique to ASP.NET MVC. They have been around a long time. It's just that MVC supports these notions particularly well. IoC is a principle, or an architectural pattern. There are quite a few definitions of IoC, but the basis behind it is always the same - it helps towards a loosely coupled architecture. DI is one way in which IoC can be applied,
according to one school of thought. DI is IoC according to
another. So far, you may be none the wiser, so I will use a bit of code based on the Contact Manager ASP.NET MVC tutorial to help illustrate the
basic problem that they or it are/is intended to solve:

Just to clear up any initial confusion, yes - the example above is more or less the same code twice. One uses LINQ to SQL (the first one) and the second uses the Entity Framework for data access. Both versions have a dependency on the data access service or layer, in that neither controller can do their thing without it. However, in both versions, the specifics of the dependency is hardcoded into the Controller. That's called "Tight Coupling". In the first version, a LINQ to SQL DataContext is instantiated and referenced, and a System.Data.Linq.Table<T> object is passed to the View. In the second, an Entity Framework ObjectContext is referenced, and a System.Data.Object.ObjectQuery<T> is passed to the View.

There is no separation of concerns here in that the data access layer is embedded in the Controller. So what's the problem with that? Well, imagine that the two versions are an example of "before" and "after". In other words, you began by using LINQ to SQL, and then were required to change the data access to the Entity Framework (or ADO.NET, nHibernate, Typed DataSets or any number of other methods). OK, you think - it's just a couple of lines that were changed. Now imagine that these Controllers had 20 or 30 Actions, and that there are 20 or 30 Controllers. Now you begin to see the problem...

"Oh, but that will never happen to me", you say. And I can to an extent sympathise with that: the only data access changes I have ever made to an application were through my own choice. Until a couple of weeks ago. We weren't expecting it at all. But it happened nevertheless and was forced on us.

When you view Data Access as a "component" of your application, you should also start to see that there are other areas in an application which could be viewed as components. An emailing service, a logging service, caching, validation etc. All of these could be implemented as components. You may already be using ready-built components such as those
found within the Enterprise Library. They could all potentially become dependencies of Controllers or even eachother. And all could be subject to change. You might decide to experiment with one, and then after some work, decide it doesn't suit you, so you need to exchange it for another. Now that happens to me quite often.

Another problem with the tightly coupled examples is with Unit Testing. If you are taking the trouble to read this article and haven't got round to a structured testing regime for your applications yet, chances are that you will. At the moment, if you write a test for the Index Action of the ContactController, you will cause a call to the database. If you take a Test Driven Design approach, you probably won't even have a database at this point, let alone any useful data in it. And if you have created a database, you need to stuff it with dummy data so that it can return something tangible. And testing against databases (when you have hundreds of automated tests to run) is slow. So you create a Mock. A mock in this case is service that simulates or mimics the database. It will generate collections for you, but you need to replace the data access code in the Controller so that the Controller is dependent on the mock object instead of connecting to and querying the database. And you need to do that every time you run the tests,
and then undo it again, which will be time-consuming and messy.

Dependency Injection

Inversion of Control really describes what happens when you move away from a procedural programming style, where each line of code is run in turn, to a more (for example) event-driven style, where code is fired as a result of external factors. In other words, in procedural programming, control of what happens and when is entirely in the hands of the programmer. In an event-driven application, the control over what happens and when is inverted or placed in the hands of the user. One of the benefits of moving away from a procedural approach to a more object-oriented style of applications development is that you need a lot less boilerplate or repetitive code. In a procedural application, if there was a need to make 4 calls to a database within a function, you would have to write code to connect to the database and interact with it 4 times. When you run the programme, it will run from top to bottom. The code is entirely in control of that. Taking a more abstract approach allows you to write the database code once (as a service or component), and to provide a means of supplying it to the function that needs it at the point it is needed (if at all). In other words, the dependency (the data service) is injected into the calling function.

It's a bit like the difference between having to walk around with this lot in your toolbag:

and this:

Imagine that the main body of the tool in the second image is a Controller. Each of the attachments that plug into it are different data access components. One is for LINQ to SQL, one for the Entity Framework and the last one uses nHibernate internally. The reason that they can so easily be swapped in and out is that they all share a common interface with the main body of the tool. The main body has been designed to expect a component that has been tooled to fit. So long as additional attachments implement the correct interface, there is no reason why you can't build a lot more - a toothbrush, for example, or an egg whisk - and be sure that they will all fit.
Ok - this example isn't perfect: the attachment or component is not providing a
service to the body of the tool so the analogy falls down a little, but the
principle behind common interfaces should be clear.

This brings us onto a key Design Principal - Code to an Interface, not an Implementation.

Right. First, we need an interface, which will define the methods that the data access
component will implement. In this example, there is only one method so far:

public interface IContactRepository
{
IList<Contact> GetContacts();
}

Now we move the actual data access out of the Controller into a separate class that implements the IContactRepository interface:

When the parameterless constructor is called, it automatically calls the second constructor that has the
IContactRepository parameter. That's what the : this(new ContactManagerEntityRepository()) does. It's called constructor chaining. And it is at that point that the dependency (the ContactManagerEntityRepository) gets injected into the Controller. But now, if you look at the Index Action, you can see that the GetContacts() method call is made against the IContactRepository interface instead of an instance of a concrete implementation of that interface (which is what the ContactEntityManagerRepository is).

If you wanted to swap the EF based data access component out and replace it
with the LINQ to SQL version, you would simply have to make one change to the
Controller. You would no longer pass in an instance of the
ContactManagerEntityRepository class into the chained constructor. You
would make that ContactManagerLinqRepository instead:

This is a lot better. The Controller is a lot more loosely coupled to
the nature of the component. And this is how both the Contact Manager and
the Nerd Dinner samples implement DI. Changes can be made quite simply, although
if you have a lot of dependencies things can be a little more complicated.
You could use Find and Replace to update multiple controllers, so long as you
can be sure you don't accidentally alter other files where the Replace operation
breaks things. Hmmm... Do you hear a faint creaking sound in the far off
distance? Maybe this approach isn't that rock solid after all, and perhaps
that's why the approach outlined above is also known rather derogatorily as
"Poor Man's Dependency Injection".

IoC Containers

Enter the Inversion of Control Container. There is a massive problem
with these: Their name. I could go on a rant here about the plethora of
simple concepts being totally obscured by the mangling of the English language,
but that's for another day. An IoC Container's job is quite simple.
You use one to create a mapping between interfaces and concrete types. The
containers you tend to see talked about most often for .NET are:

Unity
CastleWindsor
StructureMap
Spring.NET
Ninject
Autofac

At runtime, they take care of the responsibility of passing in the correct
type. There are lots of IoC containers available. Many of them are open
source or freely available. Most of them share the same features, in
that they will resolve injection at constructor level (as is required in the
above examples) or property or method level. Generally, you would use an
xml file to create the mappings - perhaps the web.config file or the container's
own configuration file. Some of them also provide an API for configuration
in code. On the plus side, xml configuration doesn't require you to
recompile when you make changes. On the downside, I dislike xml config
files.

Using StructureMap

StructureMap, at basic level is simple to use. It only takes a couple
of steps. The first is to change the Controller code so that the Interface
is passed in to the default constructor:

You see now that the original empty constructor with its chain has gone. The
thing is that the default ControllerFactory used by ASP.NET expects controllers
to have parameterless constructors, so we need to create our own
ControllerFactory, and get it to pass requests for controllers through
StructureMap. StructureMap will examine each one as it comes and look for
dependencies in the constructors, and then attempt to resolve those dependencies
with concrete types that have been registered with it. So a new
ControllerFactory class that inherits DefaultControllerFactory is created:

The final thing that needs to be done is to register the new
Controllerfactory in the Global.asax.cs, along with setting up StructureMap's
mappings between interfaces and concrete types. Within the
Application_Start() event handler in the Global.asax.cs we add:

to fulfil the second bit. And that's it. How easy was that?
OK - a lot of credit goes to Jeremy Miller who is the driving force behind
StructureMap itself, but behind that is the fact that IoC containers are a
simpler thing than most people who haven't used them realise. There is
obviously a whole lot more that StructureMap and other containers can manage for
you but they are not difficult to get to grips with. If you find that
documentation too obscure, or lacking for one of them, try a different one.

Summary

Loosely coupling dependencies is pretty much always a good idea. Poor Man's
Dependency Injection can be enough for smaller applications that you know won't
grow too much, but you can now see that IoC containers are also not that
mysterious after all.

You might also like...

26 Comments

20 October 2009 06:32 - AdamA

When is your patterns book coming out? ;) You do a great job of explaining these concepts!

20 October 2009 16:28 - Phil Steel

Hi Mike

Great post. I had a question:

Although the IoC container takes care of switching out the IContactRepository concrete instance, the method iRepository.GetContacts() still returns a list of concrete objects of type 'Contact'.

Is it best practice to abstract this type out to an interface of type 'IContact' or is this overkill?

21 October 2009 07:34 - Mike

@AdamA

Thanks for your comments, but I think if I told my wife I was writing a book, she'd divorce me ;o)

21 October 2009 08:03 - Mike

@Phil

A Contact is a domain object. It's the reason for your application. Data Access (and logging, encryption etc) are services that your application makes use of. The type of service may change, which is why you de-couple them from the main application through Interfaces.

Typically for domain objects, if you want to use polymorphism, you would create an abstract superclass (say of type Person) and then for example in a recruitment system which is intended to be used by consultants, you would create concrete implementations that inherit from that class like ClientContact and Candidate. Both of them share a lot of similar properties and behaviour, but one gives you jobs to fill (and would therefore have a Jobs collection as a property) and the other will have a CV property. One will have a MakeOffer() method, and the other will have an AcceptOffer() method.

But you would invoke a concrete type depending on which aspect of the workflow the application is handling at that point. You won't decouple your ClientContact object from the application, because it's what that part of the application is all about.

26 October 2009 16:21 - Phil Steel

Mike

Sorry, yes I understand the Domain object concept.

But in your example you say it's easy to switch between the concrete repositories 'ContactManagerLinqRepository' and 'ContactManagerEntityRepository' - LinqToSql and Ef generate their own entities under the hood so the client needs to know about which kind of Contact object (EF or L2S) it's using (i.e. which namespace), right?

So don't you need to specifiy that object in your IoC container as an interface as well?

26 October 2009 17:35 - Phil Steel

This link here re-iterates what I actually meant
http://www.asp.net/learn/mvc-videos/video-403.aspx

and here on stack overflow
http://stackoverflow.com/questions/746195/linq-to-sql-entity-framework-repository-pattern-and-dependency-injection

Look at the first link, 4 posts down: "If your interface returns objects that are created by the Linq to SQL designer, aren't you tying your interface -- and by extension the controller -- to a Linq to Sql class?"

26 October 2009 21:18 - Mike

@Phil

I checked both links and I can't find anything to suggest that you should create an Interface for the Contact class. There is no such thing as a "LinqToSqlContact" object. If you look at the classes generated by Linq to Sql and EF, when pointed to the same database, they are both "Contact" classes, with more or less the same properties.

All the controller knows is that it must obtain an IList<Contact> to pass to the View. It shouldn't know how that list was generated.

Run through the code I posted and try to replicate it and get it to work. You will soon see that the only change I had to make using StructureMap was to change the reference to the RequestedType to get it to work. No changes to namespaces either.

26 October 2009 21:42 - Mike

@Phil

Oh - I found the 4th post down (in the video link), and then worked out why you provided the stackoverflow link. At stackoverflow, John Saunders talks about not passing Linq to Sql generated objects across service boundaries because of the baggage they contain. He suggests using DTOs instead, and populating them from Linq to SQL. The DTO will be a basic Contact class with nothing but properties. But there's no hint of an IContact anywhere.

26 October 2009 22:23 - Phil Steel

Hi Mike

Yup this makes sense. I suppose the only drawback is

a) you have to manually populate your domain/business object from your LinqToSQL/EF entities or queries instead of just returning the entities across the boundaries.

b) You have to hand craft the stuff which would be done for you otherwise (like INotifyPropertyChanged.)

The reason I suggested an interface is so that you could use partial classes in each implementation so your entity could implement an interface and the interface could be passed across the boundary to the presentation layer instead. But I guess a concrete business object makes more sense.

Thanks!

18 November 2009 20:18 - Mike

@Phil

Thinking about this a bit more, your approach also makes some sense in some respects. There may come a time when you want to cross service boundaries, but don't know if and when that might happen, so you prepare accordingly. Your points rang a bell somewhere, and when I recently checked the KIGG sample source code, I see that the approach you advocate is used there. Partial classes that implement interfaces.

20 November 2009 20:21 - Evan Larsen

I just started using asp.net mvc and am loving it and have also just been getting used to IoC and DI using CastleWindsor. I have one problem though.. when My controller has like 6 components that need to be injected for the controller to work.. the constructor begins to look really ugly. Am I doing something wrong or is it supposed to be that way?

Also, I was wondering if its a waste of resources to be always initializing the components on the construction of the controller. Wouldn't tight coupling be more efficient if you only constructed the components when they needed to be used.

For instance the 6 components arnt always used in every controller's action. One action might only use 1 component whereas another might use 4.

If I used tight coupling, then when an action is called only the compoents that are being used will be constructed as apposed to constructing all 6 everytime with DI.

21 November 2009 09:24 - Mike

@Evan

If you need to instantiate say 6 services within your controller, you will have to produce some code to do that whether you use DI or not. Either way, you will end up with a similar result. If you have services that will only be used by a smalll number of methods within the Controller, you don't have to instantiate them in the controller's constructor. Some IoC containers will allow you to inject them via ActionFilters: http://www.jeremyskinner.co.uk/2008/11/08/dependency-injection-with-aspnet-mvc-action-filters/.

21 November 2009 14:14 - Sunil Joshi

Hi Mike,

Thanks a lot for the wonderful article.

Link to show how we can add structure map in web.config:-http://www.jacopretorius.net/2009/11/configuring-structuremap-using.html

Thanks again.

Sunil.

22 June 2010 02:14 - Mark

Excellent article! Very well prepared! Thank you!

13 August 2010 12:20 - Radu

I'm sorry, I just don't see why is this such great news. This is seriously ugly stuff. Basically I make an interface and implement that and I make a factory so I can change less code when I instantiate. Oh, and if I don't do that, I will need to write an XML. This is such bullshit. We've had this since '74 revolution. The developers have to admit: current decoupling technology is plain ugly. It does help, but I just can't use that. Aspect oriented programming does it much better - and it is still ugly nevertheless. We need a new programming language, like Objective C which doesn't really have method calls and thus coupling in the first place.

13 August 2010 22:37 - Erx

I had about 90% comprehension until I came across this line... public ContactController() : this(new ContactManagerEntityRepository()){}

being a vb developer who can still read c# code enough to get by, once I didn't know what that did ESP. The : part my comprehension thereafter for everything that followed dropped to less the perhaps 10%... When one thing is missing the rest becomes completely N/A and reading it or not becomes superfluous ... Which is a shame for me because you are very good at explaining things and do so with care, more so then other code bloggers who generally just draw an array of assumptions on the reader and write in a way that explains things for themselves more so than anyone else...

Anyway, thanks for the article I have bookmarked you.

14 August 2010 10:02 - Mike

@Erx

The colon after a constructor in C# is what's called a chained constructor. In other words, it calls the overloaded constructor that takes the IContactRepository object as a parameter, and makes sure that the contact repository is instantiated. I have no idea how chained constructors are managed in VB.

15 January 2011 03:12 - jmcilhinney

It's simply one constructor calling another. 'this' is equivalent to 'Me', i.e. calling a constructor of the same class, while 'base' is equivalent to 'MyBase', i.e. calling a constructor of the base class.

31 March 2012 19:35 - willem d'haeseleer

"this example isn't perfect: the attachment or component is not providing a service to the body of the tool"I disagree, if you take the abstraction to the next level you will see that the attachments do provide a service to the body of the tool, but this service is only ever used if the tool it self is being used by a human. If the tool is in use by a human you could say that that the grip of the tool is the contract between the tool and the human, sort off...

30 March 2013 15:54 - Amit Jahanabadi

One of the Best Article on DI & IoC, I have ever read. Thank You!

05 July 2013 22:49 - Chikelue Oji

This is the best article on DI and IoC that I have ever read. Thank you very much.

26 August 2014 11:22 - Preeti

Nice Article on DI. Since long i was searching for DI. Have given very good example using LINQ to SQL and Entities. Thankyou!!

16 June 2015 16:35 - Sunil

This is an excellent article and helped me clear a lot of concepts related to IOC and DI. The detailed explanation is not easy to find elsewhere.

24 June 2015 21:00 - yoyo

Hi, thanks for your explainations.
Lionel

20 September 2015 12:46 - Michael Moore

This is just the best. I have such a hard time understanding a lot of .NET concepts but this was so clearly explained. Thank you!

24 December 2015 13:58 - Ashish

Hello Mike,

I want to know what is exactly the need of dependency injection in MVC views?

Unfortunately, something went wrong and your message or comments have not been submitted
successfully. I'll try to fix whatever the problem is as soon as I can.

Thanks for your comments. They have been successfully sent to me. I will try to respond
if necessary as soon as I can.