Setting Up Dependency Injection in Web API with StructureMap

Up until recently I hadn't really used any Dependency Injection (DI) frameworks in my ASP.NET projects, largely due to them being rather intimidating to set up the first time. I mean, I barely grasp the concept of DI, so the thought of trying to implement it on my own is worrisome.

Recently, though, my group had a requirement that forced us to consider using a DI framework (which I wrote about in Custom Validation in ASP.NET Web API using FluentValidation) for an ASP.NET Web API project we're in the process of building. We needed a way to pass dependencies to multiple consumers, particularly Web API controller classes and back-end repositories. Further, we needed the solution to be testable, and to be relatively easy to change when necessary.

I started researching different DI setups, and eventually stumbled across one called StructureMap, which after just an hour of exploring, seemed to provide everything our solution needed. The worry I had foreseen was reduced to mere trepidation, and just a little more research showed the kind of power that Dependency Injection really holds.

Of course, if it helps us, it will help someone else out there; hence this post. Let's explore getting started with Dependency Injection in ASP.NET Web API, using StructureMap!

Creating the Project

Let's create a new Web API project in Visual Studio. I called mine StructureMapWebAPIDemo.

We'll end up with a project that looks a lot like this:

Setting Up the Library and Repositories

Before we do anything else, let's set up our library project. Add a new Class Library to the solution (I called mine StructureMapWebAPIDemo.Lib) with folders called Interfaces, Repositories, and DataModel. The structure will look like this:

We'll need a data model class to interface with, so let's create a class called Movie.

All the repository does is return either a collection of movies, or an individual movie (or null if given a movie ID that doesn't exist).

Now that we've got our library set up, we can integrate StructureMap.

Adding StructureMap

In the Web API project, let's add a NuGet package called StructureMap.WebApi2. On doing so, we'll see that the structure of the project has changed:

The new files are what allow StructureMap to operate in our Web API project, and if you'd like more information about them, check out the GitHub documentation. Luckily for us, we don't strictly need to know what these files do in order to use them (though understanding what you are building is always a good idea).

Modifying the Controllers

We have one controller in this project at the moment, HomeController. Let's remove this controller and replace it with our own MovieController and two actions which use the MovieRepository from earlier:

On first glance, this all seems fine and dandy. After all, the All() and GetByID() are pretty descriptive insofar as what they do. The issue arises when the implementation of the MovieRepository needs to change.

Let's say (for the sake of argument) that we need to be flexible about what implementation we want for the MovieRepository. Maybe we need to support different data storage systems, maybe we need the possibility of changing the actual code for different scenarios, what have you. The problem we have right now is that new is glue; that is, creating a dependency using the new keyword binds the dependency to the current implementation, whatever that happens to be. If the implementation of the MovieRepository changes, it's likely the code in the MovieController will also need to change.

But what if it didn't have to?

That's the core philosophy behind using a DI container: separate the implementation from the interface. In this way, if the implementation changes, the classes which need that implementation don't actually care, because the interface to the implementation didn't (necessarily) change.

Here's what we need: we need the MovieController to be aware of an interface to the implementation, not the implementation itself. We can do this by creating a private variable in the MovieController class for the repository's interface and assigning the implementation of that interface in the constructor:

This is how we tell StructureMap to inject an instance of MovieRepository into MovieController's constructor for the interface IMovieRepository.

Testing the Controllers

One of the primary benefits of switching to a DI container such as StructureMap is the improved ability to test our code. Unit testing the MovieRepository doesn't change, but unit testing the MovieController does, due to the constructor injection we're performing on it.

We're going to test two scenarios: when we call the controller's GetByID action with a valid ID, and with an invalid ID.

Valid Movie ID test

Let's write the valid ID test first. The general order of operations for any test is arrange, act, assert.

Arrange

First, we need to arrange the components being tested, as well as their dependencies. Remember that the point of this test is to test the controller, not the repository, and so we'll be mocking the MovieRepository using Moq:

Act

Now, we need to perform the action we are testing. Remember that since we are testing a controller, we will get back an IHttpActionResult response, and need to convert that to an appropriate response class (in our case, OkNegotiatedContentResult). Here's the next part of the method:

Summary

Dependency Injection's primary purpose is to separate the implementation from the interface, and allow the system to supply the implementation at a given time. StructureMap (and it's Web API implementation) provide most of the groundwork to do just that, and all we programmers have to do is:

Register the dependencies

Set up the controllers to use injection

Test

And then we can sick back and sip our margaritas. Or get back to work. Whichever.

I've got a sample project for this post over on GitHub, so go check it out!