In my last post I focused on how to unit test a new Visual Studio 2012 RC
ASP.NET Web API project. In general, it was pretty straightforward, but when I
had Web API methods that needed to return an HttpResponseMessage, it got a
little harder.
If you recall, I decided to start with the
Creating a Web API that Supports CRUD Operations tutorial and the
provided solution that came with it. That project did not use any form of
dependency inversion to resolve the controller’s need for a
ProductRepository. My solution in that post was to use manual dependency
injection and a default value. But in the real world I would probably reach for
a dependency injection framework to avoid having to do all the resolution
wiring throughout my code.
In this post I am going to convert the manual injection I used in the last post to one that uses the Ninject framework. Of course you can use any other framework you wanted like Unity, Castle Windsor, StructureMap, etc. but the code that adapts between it and ASP.NET Web API will probably have to be different.
Getting Started
First let’s take a look at the code I had for the ProductsController at the end
of the last post, focusing on the constructors and the IProductRepository field.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
The default constructor provides the default value for the repository, while the second constructor lets us provide one. This is fine when we only have a single controller, but in a real-world system we will likely have a number of different controllers, and having the logic for which repository to use spread among all those controllers is going to be a nightmare to maintain or change.
By default, the ASP.NET Web API routing stuff will use the default constructor to create the controller. What I want to do is make that default constructor go away, and instead let Ninject be responsible for providing the required dependency.
A quick aside - Constructor injection or Property injection?
This came up in one of my talks last week at TechEd, so it probably warrants some discussion here. When Brad Wilson and I made the first version of the ObjectBuilder engine that hides inside Unity and the various P&P CAB frameworks, we got to have this argument with people all the time.
While this argument looks like another one of those “philosophical arguments” that doesn’t have a right answer, I don’t think it really is. I think the distinction between constructor injection and property injection is important, and I think you can find yourself using both depending on the circumstances.
Here’s the gist of my argument: If the class would be in an invalid state without the dependency, then it is a hard dependency and should be resolved via constructor injection. It cannot be used without it. Putting the dependency on the constructor and not providing a default constructor makes it very clear to the developer who wants to consume this class. The developer is required to provide the dependency or the class cannot be created. If you find yourself doing a null check everywhere the dependency gets used, and especially if you throw an exception when it is null, then you likely have a hard dependency.
But if the class has a dependency that either isn’t required, or that will use a default object or a null object if it is not provided, then it is a soft dependency and should not be resolved via constructor injection. If you do choose to express this optional dependency via constructor, then you should either show the default value in the constructor definition or provide an override that doesn’t require it. Then if the developer wants to provide a special implementation (logging is an example that comes to mind), they can provide it via the property setter.
Dependency injection containers hide a lot of this from you, which might take you to a “who cares” kind of place. But one thing I always look for in DI frameworks is that I don’t have to change the code itself very much. It should read and be understandable without knowing anything about the DI container. If I don’t want to use a DI framework at all, the code should still express its meaning and it should still be usable. I believe that this distinction between hard and soft dependencies makes that clear.
Expressing the IProductRepository dependency
In our case, the repository is a hard dependency, so I will express it on
the constructor. Additionally, I don’t actually want the default object instance
so I’m going to delete the default constructor. It will be invalid to create a
ProductsController without providing an instance of IProductRepository.
The code now looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
If you try to run the app now, either through the web page that consumes
the API or by pointing a browser at **
It is time to bring Ninject to the party.
Using Ninject to resolve the repository dependency
Getting the NuGet Packages
In previous releases of ASP.NET MVC4, you were able to use the existing Ninject MVC3 NuGet package to give us all the required glue code. But with the RC build of MVC4, it no longer works because the MVC team changed the dependency resolution mechanism for Web API projects.
Since I can’t use the Ninject MVC3 package, I need to do something slightly
different. Instead, I will use the Ninject.Web.Common package and then
create my own wrapper class to adapt between the IDependencyResolver API and
Ninject.
When you add the Ninject.Web.Common NuGet package to your project, it does a few things to help you. So that you can skip adding a bunch of code to your Global.asax.cs file, it uses a nice little package called WebActivator to call another class when certain ASP.NET events have happened.
After adding Ninject.Web.Common to the project, open the App_Start folder and you will see a new file called NinjectWebCommon. This static class will be called by WebActivator when the application starts and stops. The Ninject.Web.Common package provided it with the code required to bootstrap the Ninject kernel.
NinjectDependencyResolver
I said we needed an implementation of IDependencyResolver that knew about
Ninject. Fortunately my good friend Brad Wilson came to the rescue again, and
pointed me to a chunk of code he’d written to do just that. Here’s my
slightly modified version of his code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | |
This file contains two classes. The first, NinjectDependencyScope, provides a
scoping region for dependency resolution. Scopes and Blocks are beyond the
scope (sic) of this post, but the gist is that you may need to provide
different service resolutions for different places in your app. The second
class is the actual implementation of IDependencyResolver, and since it is
also the global scope, it derives from NinjectDependencyScope.
Hooking it all up
Now that we have these classes, we can hook it all up. Returning to the
NinjectWebCommon static class, we only need to add one line to use our new
dependency resolver. We will add this to the CreateKernel method:
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
We simply new up an instance of the NinjectDependencyResolver and assign it
to the DependencyResolver property of the global HttpConfiguration object.
I’m still not 100% sure this is the best place to do this, but I tried a few others and it didn’t feel any better. If I later change my mind on this, or if someone can tell me a better place or way to do this, I will update this post. In the Unity sample that I link to at the end of this post, they did it in the Application class. One advantage to doing it here is that we can imagine it being done for us by a NuGet package (more on that at the end). Choose what feels right for you.
Registering our services with Ninject
The NinjectWebCommon static class already had a nice method called
RegisterServices where I am supposed to express my service bindings, so I
will simply use that. Here is mine:
1 2 3 4 5 | |
Ninject has a very friendly fluent API for binding instance types to interface
types, so with that one line I am telling it that whenever someone (in this
case ASP.NET) asks for an IProductRepository, it should give back a
ProductRepository. Remember when I said we didn’t want these kinds of
dependency resolutions spread all over our code? Now they’re not. We have them
all in one place where they are easy to see and change as needed.
Next Steps
I feel pretty good about the state of this project at this point. In my
previous post I focused on testability and the issues with having a Web API
handler that returned an HttpResponseMessage. In this post I explored how to
resolve the dependencies using Ninject. If this was a real project, I would now
feel pretty good about adding additional controllers, real repository
implementations, etc. I’m in a testable state, which I love, and my classes are
loosely coupled while still expressing their dependencies in a clear, readable
way.
I would love to see the NinjectDependencyResolver stuff become a new NuGet
package for others to use, so if someone wants to grab this code and do that,
I’m fine with it (and I assume Brad Wilson is too, since this was originally
his code). I don’t do enough full-time web development to be a very good
maintainer of such a package, so it really would be better for someone else to
do that instead of me.
I mentioned at the top that you can do this kind of thing with a number of different dependency injection frameworks. If you want to see an implementation that uses the patterns & practices Unity container, there is one called Using the Web API Dependency Resolver up on www.asp.net.
If you are looking at the new ASP.NET Web API framework for building out your new REST APIs, hopefully you’ve found these two posts useful. Let me know!