Using NuGet Part 1: NuGet Basics

Looking for a better way to reference external libraries? NuGet may be just what you’re looking for. This is Part 1 of 3 blog posts about NuGet. This series of blog posts will cover some basic information on what NuGet is as well as how you can create and consume your own .NET and native C++ NuGet packages.

What is NuGet?

NuGet is a Visual Studio extension that allows you to search for, install, uninstall and update external references in your projects and solutions. Until fairly recently, NuGet only officially supported .NET libraries, but it has now grown to support native C++ libraries as well. NuGet refers to these external libraries as NuGet packages. NuGet comes installed with the more recent versions of Visual Studio, but you can download it from here if you don’t already have it.

NuGetPic1

This is the NuGet Package Manager. This is what you will be looking at when you interact with NuGet most of the time. It is from here that you can manage your existing packages as well as find new ones to install. You may also notice that you can have multiple sources for NuGet packages.  The public facing and default source is nuget.org while my instance of Visual Studio has other internal TechSmith sources defined so that our internal libraries are only consumable by TechSmith developers. You can also add a local folder as a source so that you can create and test packages locally without publishing the package for others to see.

Why should you care?

NuGet is pretty much an industry standard and Microsoft has been presenting it for a while as their recommended way to reference external libraries, especially for .NET. It provides a centralized location for you to find useful libraries as well as distribute your own. It should just make your life as a developer a whole lot easier.

What is a NuGet package?

A NuGet package is .nupkg file that contains all of the content needed to reference an external library. This content is typically one or more DLLs as well as some metadata describing the package. Less often, the package can also contain other things like source code, debug symbols, and PowerShell scripts that run when the package is installed.

What happens when you install a NuGet package?

  1. The package is downloaded to a “packages” folder next to your solution.
  2. Any other NuGet packages that the package is dependent on are automatically downloaded and installed.
  3. References to the package’s contents and its dependent packages are set up automatically. For .NET packages, this means that references to the package’s DLLs are added to one or more projects automatically. For native C++ packages, this means that project include directories, library directories, and LIB dependencies are set automatically at build time and link time.

Consuming a .NET NuGet Package

As a sample, I have a very simple .NET WPF application already created. The app has an input text box, and output text box, a single button and a method that is called when that button is clicked. This is where we will plug in our usage of a consumed NuGet package. This app will take the text input and try to determine which language the text is written in.

NuGetPic2

First, let’s remind ourselves how we would add an external assembly reference without NuGet.

A common workflow is to…

  1. Right-click your project.
  2. Select “Add Reference”.
  3. Find the DLL for the library and select it to be added as a reference.

This is fairly simple and works pretty well, but there are some downsides.

  • A reference to this DLL needs to be added individually to every project where it is needed.
  • The DLL needs to be checked into source control so that other developers and the build server have access to it.
  • Depending on what type of source control you are using, all developers’ workspaces need to be updated to check this DLL out.
  • Build definitions may also need to be updated so that they know where this file is and how to check it out as well.
  • Depending on how updates work for a particular library, all developer and build server workspaces may need to be updated again once the library is updated.

So, there is a little bit of overhead with adding and maintaining a reference like this. Let’s see how to do the same thing with a NuGet package instead.

  1. Right-click your solution and select “Manage NuGet Packages for Solution”.
  2. Click the “Online” tab on the left, and make sure that the nuget.org package source is selected.
  3. Search for a package in the top-right. We are searching for “language detection” for this sample.
  4. Select a package to install. The top two packages seem pretty reasonable to use, but we will choose “ALanguageDetection” since it has existed longer and has been downloaded by more people.
  5. Select the projects that you want to install the package to.

NuGetPic3

Note: Make sure to manage packages at the solution level rather than on individual projects. Otherwise you can run into problems where you update a package on one project without updating the same package for other projects in your solution. Referencing multiple version of a the same NuGet package within the same solution should be avoided.

The package is now ready to use. We can start using the package’s namespace and then plug the language detection code into the button’s click-handler.

using Allan.Language.Detection;

private void Button_Click( object sender, RoutedEventArgs e )
{
   var languages = Detector.DetectLanguage( inputTextBox.Text );
   var topLanguage = languages.OrderBy( l => l.Distance ).First();
   var langString = new CultureInfo( topLanguage.Language.Code ).DisplayName;
   languageTextBox.Content = langString;
}

This code uses the Detector object to detect the language of the input text, finds the language that the text most closely matches, and then outputs that language’s name.

We now have our expected results.

NuGetPic4

Easy enough, right? Now that your code references and uses the NuGet package, you can commit your changes and other developers and your build server should be ready to go without making any additional changes. In contrast to the list of disadvantages when referencing libraries in the traditional way, there are advantages to using this NuGet package. Using this NuGet package should require very little maintenance going forward.

  • You don’t need to check the DLLs into source control.
  • Visual Studio on other computers will know that your solution references the ALanguageDetection NuGet package and will download it before a build automatically.
  • If the package is updated by an developer, no one else, including your build configurations and build servers, should need to update anything after grabbing the latest code.

Consuming a Native C++ NuGet Package

Our sample app this time is built with MFC and will simply detect which operating system we are currently running. TechSmith has a NuGet package named TSCUtl that we will be using to provide this functionality. This app has a single button and a method that is called when that button is clicked.

NuGetPic5

Just like we did for .NET, first, let’s remind ourselves how we would add an external assembly reference without NuGet.

A common workflow is to…

  1. Right-click your project.
  2. Select “Properties”.
  3. Add additional include directories under C/C++ > General
  4. Add additional library directories under Linker > General
  5. Add additional dependencies under Linker > Input

Referencing libraries this way has similar disadvantages to those for .NET libraries.

  • A reference to the .h, .lib, and .dll files  needs to be added individually to every project where it is needed. Multiple configurations like Release and Debug only make these settings more tedious to set up.
  • The .h, .lib, and .dll files all need to be checked into source control so that other developers and the build server have access to it.
  • Depending on what type of source control you are using, all developers’ workspaces need to be updated to check these files out.
  • Build definitions may also need to be updated so that they know where the files are and how to check them out as well.
  • Depending on how updates work for a particular library, all developer and build server workspaces may need to be updated again once the library is updated.

Once again, let’s see why NuGet is awesome. I install the TSCUtl NuGet package in the same way that I installed the ALanguageDetection package above, but I am using TechSmith’s internal NuGet server this time since the package is private to TechSmith.

NuGetPic6

The package is now ready to use. We can include the package’s header file and plug the operating system detection code into the button’s click-handler.

#include <TSCUTl\TSCUtlWndVersion.h>

void CMFCAppDlg::OnBnClickedButton()
{
   if (TSCUtl::TSCWindowsVersion::GetWindowsVersion() == TSCUtl::TSCWindowsVersion::Win7)
   {
      AfxMessageBox( L"Windows 7" );
   }
   else if (TSCUtl::TSCWindowsVersion::GetWindowsVersion() == TSCUtl::TSCWindowsVersion::Win8)
   {
      AfxMessageBox( L"Windows 8" );
   }
   else if (TSCUtl::TSCWindowsVersion::GetWindowsVersion() == TSCUtl::TSCWindowsVersion::Win8_1)
   {
      AfxMessageBox( L"Windows 8.1" );
   }
   else
   {
      AfxMessageBox( L"Unknown OS" );
   }
}

This code calls GetWindowsVersion() and looks at the result to determine which operating system we are currently running.

NuGetPic7

Using this native C++ NuGet package is way easier and requires less initial work and maintenance to reference an external library compared to editing all of the project properties yourself.

  • You don’t need to check the .lib or .dll files into source control.
  • Visual Studio on other computers will know that your solution references the TSCUtl NuGet package and will download it before a build automatically.
  • If the package is updated by a developer, no one else, including your build definitions and build servers, should need to update anything.

One other advantage of using NuGet in this sample was that all dependencies for TSCUtl were brought in automatically. If we look at TSCUtl in the Package Manager, we can see that it depends on three other NuGet packages. These three additional packages are placed in the “packages” folder and referenced automatically just like TSCUtl is. This automatic dependency resolution is one of my favorite and most useful features in NuGet.

NuGetPic8

Next up : (Coming Soon) Part 2 – Creating .NET NuGet Packages

Links

NuGet Downloads and Installation
NuGet.exe Command-Line Reference
NuGet Package Restore
NuGetMustHaves.com – A Great Site for Finding Packages and Interesting Stats

Author
Brett Lesnau

Brett Lesnau has been a Software Engineer at TechSmith since 2008 where he has worked on various teams including Snagit and Cloud Services. He has a B.S. and M.S. in Computer Science from Michigan State Univeristy and enjoys creating and playing video games. He can't wait until his daughter is old enough to be a gaming partner.