Managing Dependencies with NuGet
|April 6, 2011||Posted by david under Programming|
Note: This was presented to the Tampa C# Meetup on April 6th, 2011.
Most large .NET projects will use a number of libraries and frameworks. Those dependencies of your project will have their own dependencies. To make it more complex, those libraries may depend on other libraries, and in some cases – on each other.
The Dependency Management Problem
The dependency problem is something that strikes fear into the heart of many a developer, and even more in to the lead or manager. Given the pace of advancement, for example, consider the popular IoC framework Ninject. Between Jan 1, 2011 and Apr 5, 2011, there have been four different versions (2.0.1, 22.214.171.124, 126.96.36.199, 188.8.131.52). Not too many, but multiply that against a project with six or seven dependencies, and then add in the cross dependencies, and you have a nightmare.
There are a number of solutions to this complexity. Here are a few I have seen:
- The Ostrich – You sidestep the problem by not using any external libraries. Sadly, this is more common that you might imagine, but it also negates one of the major benefits of .NET and significantly increases development time.
- The Tyrant – The team locks down all dependencies at the beginning of the project. Usually by checking in to their source control (you do use source control – right?) system all the binaries needed and never update it for the life of this project.
- The Kinder More Gentle Tyrant – Similar to The Tyrant, the team locks down the dependencies at the beginning of the project, and check in either the binaries or the source into source control. During the development phase, they do not update their dependencies, but once the project is complete they will upgrade as part of a future release. Note: this is the norm I see in most projects, and tends to be very successful.
- The Anarchist – The team uses whatever version of the library of choice they happen to find that day. Each day starts with the ‘fixing of the project’ to work with whatever version they happen to get.
In all of these solutions, the focus is on controlling how the project uses the dependency. However, I have seen very few places define a process for determining where to get a version, monitoring when new versions are released, or the process for evaluating why to use a new version. Usually a new version is used to address a specific issue the team has encountered. In short, this becomes a reactive and unplanned part of the process. This limited amount of analysis is the norm, but it gets worse. When was the last time you considered the dependency of a dependency? For example, consider FluentNHibernate. This depends on NHibernate version 184.108.40.206 or higher.
So have I scared you away from using libraries yet? Well, I hope not. This is the problem NuGet solves with elegance and ease. So let’s get to it.
The first thing you need to do is get NuGet. You have two options available, the easy way, and the really easy way. Of course you need to make sure you have the right prerequisites already installed before installing NuGet.
- Visual Studio 2010 (kind of a given)
- PowerShell 2.0 (already installed if you have Windows 7 and Windows 2008 R2)
Option 2: The Really Easy Way – Use Visual Studio Extension Manager
Go to Tools –> Extension Manager … and launch the Extension Manager. Select Online Gallery, then search on NuGet. Select NuGet and install it. So why do it through the extension manager? Look closely at the picture and you will see my current situation where I need to update. The Visual Studio Extension Manager will managing updating the NuGet Package Manager as needed. It won’t do it automatically, but it will tell you when it is available, and you can click the Update button when you are ready.
In fact, when a new update is ready, you will get this balloon notification (in Windows 7) letting you know it is available. Just follow the standard Visual Studio process of updating extensions. Ironically, you will be using Visual Studio to manage the dependency you will have on the too you will you use to manage you project dependencies.
When you are finished installing, and restarted Visual Studio, just kick off a project. For my sample, I started a Windows Console Application. You would right click on the References folder and select Add Library Package Reference. We are going to add FluentNHibernate, since that was the example I used above. You will notice the Add Library Package Reference looks a lot like the Extension Manager, and it works pretty much the same. Select the Online block on the left, then click in the search bar and type ‘FluentNHibernate’. The center panel should show you the package with a button to start the install. Click the install the button and watch the magic. NuGet display a window showing progress, and you may notice your references section changing as well. Here is the before and after for your references section.
You can see that the package added FluentNHibernate, but it also added NHibernate and its dependencies like Castle.Core. That’s all you need to do to start using FluentNHibernate. No need to go to the web site, download the zip, build if needed, move the assemblies into your shared library directory, and then add references. Less clicks means more efficiency.
Using the NuGet Command Line
While the NuGet visual user interface is amazingly easy to use, there are some that still need to feel the love of the command line. If you are one of those, don’t worry, NuGet gives you some sugar too. If you notice, we are still missing the database engine we will use, so lets add it using NuGet. For this example, I will use Sql Server Compact edition. Instead of the visual add package dialog, I went to to the NuGet website and found the package I was interested in the gallery. Right on the gallery page for Sql Server Compact, it displays the command line needed to install. You just copy the text in the black box and paste in the Package Manager Console in Visual Studio.
So what kind of packages can you install? As of April 5, 2011, there are 1103 packages available. This might be a bit overwhelming, so take your time and just explore the gallery. You can also follow Scott Hanselman’s NuGet Package of the Week on his blog. I also suggest you follow Scott’s NuGet Action Plan.