Introduction

Dependency Injection is a nice design pattern that makes your code a bit more nimble and allows for better separation between your tiers. This article goes into detail on how we used Dependency Injection when building Recarded.com, and how programming towards an interface, instead of a concrete class, not only makes Test Driven Development (TDD) easier, but also allowed us to be more flexible when we had to change our implementation due to forces outside of our control.

Background

Back in 2006, a work colleague and myself started a side venture together. We set out to create a gift card marketplace for users to sell their unwanted gift cards and to buy gift cards at a discount. This isn't your typical business venture because aside from trying to create a profitable business, we also set out with the following goals:

Do everything ourselves in our free time.

Do things 'Right'. Between Jess and myself, we have almost 30 years of web development / architecture experience, and we wanted this site to be our pet project for using the latest technologies and sticking to solid design patterns and best practices.

Give back to the development community. We love technical blogs and communities such as CodeProject that save you hours of work and learning when you can Google an issue or an idea and you stumble upon another developer that has gone through the headache for you. By posting some interesting learning or experiences we came across while getting Recarded.com off the ground, it allows us to give back and to better justify the countless hours we dumped into this site (even if it never turns a profit).

Project Layout

Below is an overview of our project structure, but don't feel this is exactly how you should setup your ASP.MVC projects. Every developer tends to have their own flavor of solution structure, balancing flexibility with complexity. Our structure has evolved over the past two years quite a bit, and there are still some improvements we would like to make (e.g., create a project just for interfaces and data models).

Recarded.Tests

We list this one first because it is the most important. My partner Jess is crazy Pro-TDD, and although prior to this project my TDD was really more like developing and creating Unit Tests at the same time, I wanted to do true TDD, and followed his lead here, and promised to always write the tests first. People can argue and persuade you all they want about the benefits of TDD, and prior to this project, I probably have read and heard them all, but to be honest, when I am in the real world, I would start down the TDD path and get so time crunched by the client, I would slip back to the old way of doing things. I did keep my promise for this project, however, and I have to say, I will never go back to my old ways. I won't bother selling you on the benefits, for if you are like me, it won't sell you until you try it yourself.

Some could argue a structure where you have a test project for each project; for example, we could have Recarded.Services.Tests and Recarded.Data.Tests instead of having all our tests in one project. We will probably evolve to that soon, but this is the current state of our application.

Recarded.Web

Recarded.Web is our ASP.MVC application, the entry point into the site. /Content contains our images, JavaScript, and CSS used within the site. /App contains the meat of the application, such as the Controllers, Views, and ViewModels. The natural tendency is to have the Domain Models be passed into the Views, but we soon started to need specific properties that were really view specific and not part of the domain model. Having the Views take in ViewModels instead of Domain Models makes it easier to adjust the presentation layer without having to bubble up through to the Data tier for something that really is presentation specific.

Recarded.Services

Here is our broker layer. The Recarded.Web layer will not call the Data Access Layer directly, it will instead use our Service Layer to get what it needs. This layer of abstraction is usually used to get the raw data from the DAL and further process it, for example, apply filters based on security, paging, etc.

Recarded.Pipelines

We brought the Pipelines project into the solution to handle activities that are better suited for a workflow engine. If you are familiar with Windows Workflow Foundation, that is the type of functionality you would find in this project. We were actually leveraging Windows Workflow Foundation for our order processing until we ran into the issue described in more detail in the 'Why Dependency Injection' section.

Recarded.Data

This is our Data Access Layer. Here, you will find our Data Access, Pipes and Filters functionality, our Domain Models, and some utility classes. At some point, we might actually bring our Domain Models into a separate project, but for now, they are located here. We use a service / repository type pattern, and are leveraging LINQ to SQL for our Data Access. If there is interest, I can go into more detail around this, but for now, you can just understand we have an Interface for each Repository (e.g., ICatalogRepository) and than a concrete implementation of that Interface (e.g., SqlCatalogRepository).

Why Dependency Injection

So, the big driver of why I wanted to write this article is because as a developer, sometimes, you just code or architect something in a particular manner because that is what your co-workers were doing, or that is the way a respectable blogger implemented it, etc. I think I was this way around Dependency Injection and programming towards an interface. The first time I used this pattern was with a past client of mine when I architected snow.com for Vail Resorts. The site uses Sitecore as their CMS, and Vail Resorts actually gave me a requirement that they wanted to make it so they are not dependent on Sitecore for their CMS. So, if they want to change to some other CMS (Ektron, home grown, etc.) in the future, they can easily do this without a whole bunch of rewrite. Now, the odds of them swapping out their CMS anytime soon is probably very low, but it was a requirement, and I ended up architecting a solution that uses Dependency Injection to resolve which repository to use, and the Presentation Layer (ASP.NET) doesn't even have a reference to sitecore.dll.

A lot of people will say coding towards an interface and using Dependency Injection is great because it allows for easier TDD, and you can swap out classes at will as long as they implement the same interface. Well, I was already sold because of the TDD aspect, but to be honest, I really never saw us having to swap out classes being a big selling point. If you take Vail Resorts for example, if they never change their CMS until their next big redesign, that additional work we did to make the application CMS agnostic is essentially overhead and a waste of resources.

Well, I became a full fledged believer with Recarded.com because we actually had to change out two implementations; two implementations I thought would probably be part of our code for quite sometime. Because we were using Dependency Injection and programming towards an interface, however, we could just build out the implementation of the interface and change Bootstrapper.cs, and we were good to go. The two instances I am referring to is we initially coded our eCommerce site to use PayPal as our Merchant and Gateway for payment processing, and we were leveraging Microsoft's Windows Workflow Foundation to process orders (submit, cancel, refund, charge, etc.). PayPal's service and API was not quite up for what our requirements dictated, so we actually had to abandon them as our Payment Service provider. We ended up going with Authorize.Net, and with Dependency Injection, we just needed to create an AuthorizeNetPaymentService that implemented our IPaymentService interface and then tell our Bootstraper to use Authorize.Net instead of PayPal.

The other implementation swap was we were using Windows Workflow Foundation for our order processing. Workflow Foundation is pretty sweet, and we had a pretty great implementation for our order processing if I do say so myself, but when we changed from the standard RackSpace hosting to Rackspace Cloud, we were met with trust issues (more info: our blog). With Dependency Injection, we just had to code a new pipeline that implemented our IPipelineEngine, swap out our WindowsWorkflowPipeline class, and then update the Bootstrapper.cs file.

The Implementation

The same pattern is basically used throughout the entire application, so we should be able to just walk through hitting one page of the site and bubbling up through the tiers and see what is going on, and you should get a pretty good feel for how Dependency Injection can be used nicely within an ASP.MVC application (or anywhere for that matter). If you are to hit http://www.recarded.com/GiftCards, our routing table will take you to the CatalogControllerIndex method.

Here is the constructor of our CatalogController. Dependency Injection essentially is the act of the application handling what concrete services should be passed into this CatalogController constructor method - for this class is dependent on these parameters or it can't be instantiated - hence the term Dependency Injection.

When our web application starts up, this block of code will get fired. The Bootstrapper.ConfigureUnityContainer() method specifies which concrete classes we should use for when a dependency is resolved.

Here, we are registering instances for each type of interface within our application. So, the last piece of code in the above snippet is telling Unity, if the application is looking to create a class that implements the ICatalogService, use the CatalogService, and resolve the three parameters that the CatalogService is dependant upon. You can also see how in the beginning we were using a FakePaymentService for testing; we then got the PayPalPaymentService in place, and it was working great using their Dev Sandbox. We then moved to AuthorizeNetPaymentService because they fit our model better. All of these Payment Services implemented the IPaymentService so they could easily be swapped out with each other just by commenting and uncommenting out a line of code.

Unity (and most other Dependency Injection frameworks) is also fully configurable via the web.config, but within our solution, we are doing it within code. There are pros and cons to both; doing it within code is a bit faster, more easily testable, and less breakable by someone fudging with the web.config. This locks the application down more tightly, and you can test this requirement since it is in code and it is kind of difficult to test the web.config. You will not be able to compile if you are trying to register a concrete class that doesn't exist or does not implement the appropriate interface.

Of course, all of the Dependency Injection doesn't have to be within a constructor; you can use DI within a method as well, for example:

Here, we are just using a Singleton pattern to ensure we are only using one Unity instance. If the Unity Container doesn't exist yet, then we will create it and configure it based on the config file.

Points of Interest

We are planning on turning this into a series to discuss various patterns, headaches, and successes we ran across while getting our site off the ground. Some future article themes under consideration are given below. Feel free to leave a comment on what you would like our next articles to center around.

jQuery Validation plug-in

Securing ASP.MVC pages and using the [ValidateAntiForgeryToken] attribute

Comments and Discussions

1. You go through the config in your code instead of the config file, but then in your last example for the DIFactory you go back to using the config file without any explanation. There's a lack of consistency here.

2. I could be wrong on this, let me know if I am, but I think there's an error in your code.

First I'd like to say that the article was well written. I disagree with a few of the techniques though. For instance, When you build up your IUnityContainer, it seems that you use RegisterInstance for almost all of the dependencies. I typically use RegisterType unless I need to register an object implementation that has very specific property values. When I say specific property values, I mean values like Id's or names.. numbers and strings.. very specific dependencies. Most of your Interfaces that you've registered have dependencies that are can themselves be represented as Interfaces. With this being the case it makes more sense to use register type to populate your container with all of your dependencies. First an example:

Imagine you have an interface with a constructor and the following dependencies..

There is no need to RegisterInstance to use IcustomerService. It's more expensive to create the object instances to add them to the container when that's what the container does in the first place. A better solution would be to do this in your bootstrapper:

Notice that with this approach, I did't have to new up a bunch of objects. Instead, I simply specified the type mappings. Now you can simply use:

var customerService = _container.Resolve<ICustomerService>();

Unity will resolve an instance of your CustomerService implementation with all of the required dependencies.

The next criticism that I would make is that IMO it looks like you've placed a lot of code in your controllers which doesn't promote strong layering of your architecture. I personally believe that your controllers should not need to know about any services or repositories. I would recommend creating ViewModel classes to add a layer of abstraction between your Controller and your Service layer. Each layer is only concerned with executing a request to the layer directly below it as well as responding to requests to the layer directly above it. This will keep your layers decoupled and therefore flexible.

The layered architecture would look something like this.

Views / Controllers (Presentation Layer) use -> ViewModels / ICommand implementations (Application Layer) use -> Service interfaces (could be local but designed to easily be changed to WCF or other SOA type services. Service Layer -> Delegates work to domain entity objects that are retrieved and saved using your Repository implementations. Domain Layer -> Which eventually use a UnitOfWork pattern to persist data changes of your domain entities to your data layer (Data Access / Infrastructure layer).

I really hope that someone finds this useful. Once again, thanks for writing the article.. Your head is in the right place.

Thanks,

Buddy James

Check my .NET Development blog www.refactorthis.net where I have a couple of articles regarding DI using the Unity container.

It would be nice to provide for unity links and which project have to referance it ?And some best practices... For example if I have 100 or more repository class, do I have to define all of them separetely in the configuration, or is there a way more simple ?

To me there are three main parts to dependency injection using an IoC container, which can be summarized as Design-Register-Resolve:

1) Design components so that dependencies can be injected as interfaces via constructors, method parameters or properties.

2) Create and configure a container that maps interfaces to concrete types, with appropriate lifetime policies.

3) Use the container in application code to get instances of your components to work with, ie, unityContainer.Resolve<t>()

While you've covered 1) and 2), 3) doesn't get much attention. Maybe you could explain how the UnityControllerFactory works as that would show how the underlying Unity container is used to resolve controller instances. Otherwise it's all a bit magical!

I thought one reason to go with DI was that you didn't have to have references to classes and recompile. Don't you have to recompile every time you change something? With something like spring.net, all you would have to do is change a config file to implement an interface or base class.

Yes RAEdwards that is a possibility, I actually call that out in the article:

Unity (and most other Dependency Injection frameworks) is also fully configurable via the web.config but within our solution we are doing it within code. There are pros and cons to both; doing it within code is a bit faster, more easily testable and less breakable by someone fudging with the web.config. This locks the application down more tightly and you can test this requirement since it is in code and it is kind of difficult to test the web.config. You will not be able to compile if you are trying to register a concreate class that doesn't exist or does not implement the appropriate interface.

If you want to see how Unity can work with just web.config configuration to dictate which concrete classes get used, you can go here.

Sacha, don't apologize for adding to the discussion, there is always a number of ways to do things, in fact we originally were using StructureMap for DI but it too had trouble in the RackSpace Cloud and it's trust issues so we swapped it out with Unity. Thanks for the Castle link.

Sorry mate, but the way you said what you said WAS rude. So I responded in kind. My initial post in this forum post did not illicit you telling me to stick to WPF, which I felt was completely condescending.

So it seems we have offended each other now. How useful is that. Like I say I actually did find your comments, very very rude actually.

Sacha Barber

Microsoft Visual C# MVP 2008-2010

Codeproject MVP 2008-2010

Your best friend is you.I'm my best friend too. We share the same views, and hardly ever argue