RSS

Creating Your Own NuGet Package, Part 1

Hello, NuGet

I find NuGet to be pretty awesome. Even though it’s several years old, it still has that new car smell to me.  We recently started using the NuGet Package Restore feature, which has helped improve our CI builds.  But like leather bucketseats, the feature I’ve wanted to have for a few years is to create my own NuGet package.

Why Create Your Own NuGet Package

When is this useful?  Do you have a library of utility functions that you want to share with others, or maybe one that you have used in multiple projects?  We have a library of utility functions that most of our other projects use.  Every time we make a change to this library, we have to manually copy the new DLL across all projects. Yuck. Manual process.

NuGet to the rescue!  We can slap this library into a NuGet package, and then fork the new version easily through NuGet.

The Pieces

You will need three small pieces in order to create your first NuGet package:

  1. The NuGet.exe command line utility.
  2. The files you want to package (i.e. a class library).
  3. A specification (.nuspec) file.  We’ll get to that in a minute.

Let’s Get Started

Starting with a simple example, let’s create a new Visual Studio solution.

  1. Create a new C# Class Library (File –> New Project –> Visual C# –> Class Library) called MyMathLibrary.
  2. In order to watch NuGet work it’s magic, let’s go ahead and create a class in here called MyMath, and give it a single static method, Sum.
  3. Build the solution.  (you can use the default Debug solution configuration).
  4. We’re going to keep it simple and do all of our NuGet stuff in a separate folder.  Create C:\Local-NuGet-Feed.
  5. Create a folder in here called output (we’ll get to this later).
  6. Add the NuGet.exe command line utility to the C:\Local-NuGet-Feed folder.
  7. Open the folder where the project you just created lives. Navigate to the output folder, bin/Debug, and grab the .dll file (MyMathLibrary.dll).  Copy (or move) this file into C:\Local-NuGet-Feed folder.
  8. Create a blank file, and name it MyMathLibrary.nuspec.

The Specification File (.nuspec)

Let’s fill in our .nuspec file with some XML (thanks to Rick Shott for the original example):

<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
    <metadata >
    <id>MyMathLibrary</id>
    <version>1.0.0.0</version>
    <authors>athenahealth</authors>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>A library of global-use math functions.</description>
    <language>en-US</language>
    <projectUrl>http://www.athenahealth.com/</projectUrl>
    <licenseUrl>http://www.athenahealth.com/license</licenseUrl>
    <tags>Awesomeness</tags>
    </metadata>
    <files>
        <file src="MyMathLibray.dll" target="lib" />
    </files>
</package>

Most of the metadata is self-explanatory (id, authors, description).

  1. The target attribute specified in the <file> tag is the folder where the file lives (either a relative or absolute path).
  2. You can use wildcards for the filename in the src attribute of the <file> tag. For example, if you specified My*.dll, the package would include all .dll files that start with My.
  3. There is one thing worth mentioning about the <version> tag.  THIS value is what dictates when consumers see a new version of the package in NuGet.  In other words, you can change the content of your files in the package, you can change the version number in the assemblies, but consumers will not see a new version until you change this value.

Creating the Package

Alrighty.  Now we’ve got our .nuspec file, let’s create a package.  For this, we’re going to use the NuGet.exe command line utility.  Run the pack command like this:

nuget pack MyMathLibrary.nuspec -basepath lib\ -o output\

Bingo! You should now have a single .nupkg file in your output folder.  You will also notice that NuGet generates the name of the .nupkg file by concatenating the values that you specify in the <id> and <version> tags in the .nuspec file.

Consuming the Package

After all, what good is our new call if we can’t smell the tires (am I the only one who likes the smell of new tires?)  Ok, I digress.

All that we need to do to see our internal packages in NuGet Package Manager is add a new package source.  It’s really that simple.

(In Visual Studio 2012, this is under Tools –> Options –> Library Package Manager –> Package Manager Settings).  If you want to try out a cool new trick, just press Ctrl + Q in Visual Studio and type “package manager settings“; then Enter. Neato!

Choose “Package Sources”.  Click the “+”, and give it an arbitrary name (i.e. Local Package Feed), and enter your local path to the .nupkg output files as the source, C:\Local-NuGet-Feed\output.

Now, open up Nuget Package Manager (or Ctrl+Q, nuget package manger”, if you like).  You will see your new package source listed in Online (right under nuget.org).  Sweet.

Updating the Package

Let’s watch NuGet do it’s magic, shall we? Create a new project in Visual Studio (this time a Console Application), and call it NuGetTester.  Use NuGet Package Manager (Ctrl+Q coming in handy yet?), and add the MyMathLibrary package.

Expand References, and then double-click on MyMathLibrary to open the library reference in the Object Browser.  You can see that there is one class, Math, with one static method, Sum.

Return to MyMathLibrary, and now let’s add a second method, Product.  Build the project and copy the .dll into our NuGet feed folder.  REMEMBER that we need to change the version in the .nuspec file.  Open MyMathLibrary.nuspec increment the version number to 2.0.0.0.  Run the pack command again.

Return to NuGetTester, and open NuGet Package Manager.  If we look at our Local Feed, we see that we can now install the update to MyMathLibrary, and we also see that it’s on version 2.0.0.0.  If you examine the reference again in Object Browser, you see our new Product method in MyMath class.  Score.

Hosting the Package Feed

A locally-hosted feed may not be terribly useful, so I’m sure most of you want to host your internal packages on a server.  As long as the folder contains the .nupkg files, that folder can live wherever you want it to.

The simplest solution that I would recommend is to create a share folder on a server (i.e. a build server is a great idea).  This is a great way to get up and running quickly.

Another neat little trick is to try running post-build commands to automatically move your .dll files automatically to the NuGet feed folder, then automatically kick off a nuget pack command.  Now throw this on a build server, trigger it after your CI builds, and it’s even cooler.

 
Leave a comment

Posted by on January 3, 2014 in C#, NuGet, Visual Studio Tricks

 

Creating Your Own NuGet Package, Part 2

Automagically Using NuGet with a Project

Want to automate things even more?

For this example, find a Class Library project that you like.  Open a command prompt and navigate to the folder where the .csproj file for that project is.

nuget spec

Bam. Now you have a .nuspec file created automatigically.  You’ll notice some strings that look like some kind of replacement tokens:  $abc$.  We’ll get to these in a minute. They’re pretty awesome.  To make full use of this next step, though, we’ll want to a few quick things first:

  1. Open the .nuspec file that was created.
    1. Change or remove:
      1. <licenseUrl>
      2. <projectUrl>
      3. <iconUrl>
    2. Change <releaseNotes> to whatever you would like (having nothing here is fine too).
    3. Change <tags> to whatever you would like (having nothing here is fine too).
  2. Open your project’s AssemblyInfo.cs file, and enter some values for:
    1. AssemblyTitle
    2. AssemblyDescription
    3. AssemblyVersion

Are you ready for something really cool?  Go back to your command line (in the same folder where .csproj is):

nuget pack

Check out your package in NuGet (using whatever Package Source you use to host it).  All of the metadata from AssemblyInfo.cs is automagically used to replace those $abc$ tokens in the .nuspec file.

Even cooler– NuGet figured out the dependencies of our project and added those as well!

Updated NuGet

Want to make sure you have the latest version of NuGet?  Let’s NuGet… NuGet!  After all, NuGet is pretty awesome at updating packages, why not letting it updating itself?

nuget update -self
 
Leave a comment

Posted by on January 2, 2014 in C#, NuGet, Visual Studio Tricks

 

Adding other NuGet Package Sources in Visual Studio

If you use NuGet package sources, you will need to add a new package source to your preferences in Visual Studio.  In VS 2012 and 2013, this is under Tools –> Options –> Library Package Manager –> Package Manager Settings –> Package Sources).  If you want to try out a cool new trick:

Ctrl + Q 
package sources
Enter

Neato!

Now click on “+”, type in a name for your package source. You can use either a UNC share path or, if you have hosted your NuGet packages on a NuGet server, you can enter a URL.

Now go to the NuGet Package Manager (Ctrl + Q, nuget package manager, if you’d like) and you’ll see your new package source listed right under nuget.org.

 
Leave a comment

Posted by on September 25, 2013 in C#, NuGet, Visual Studio Tricks

 

Using additional NuGet Package Sources on a Build Server

Now we can see the new package source on our machines, and download all kinds of fun things from it. But how do we give other servers (e.g. a build server) knowledge of this new package source?

NuGet already thought of this (thank you kindly).  Check out the NuGet.targets file (once you’ve enabled Package Restore on the solution).  You’ll want to look for a <PackageSources> element.  It may be a little convoluted, and you’ll see a few Condition=” $(PackageSources) = ” thrown around (just ignore those).  What you are looking for is the element itself.

By default, if you do not specify any package sources, NuGet will use https://www.nuget.org/api/v2/.  The minute you specify a package source, NuGet will NOT use the default nuget.org package source unless you explicity say to.

That just means you’ll need to add BOTH your new package source, and the NuGet default source (in a semi-colon separate list).  You will add these to the <PackageSources> element.

<!-- NuGet command -->
<!-- ... -->
<PackageSources ...>
https://www.nuget.org/api/v2/;\\MYSERVER\MySharedFolder
</PackageSources>

Now your can freely enable NuGet Package Restore and your build server can find your packages with ease!

 
Leave a comment

Posted by on September 24, 2013 in C#, NuGet, Visual Studio Tricks

 

Setting Up Your NuGet Package Source

Setting Up Your NuGet Package Source

Assuming this is for internal use only, your best bet is likely going to be creating an internal nuget server or creating a network share (the network share is considerably slower than the nuget server) to house all of your NuGet packages.  If this is meant to be externally accessible, then you might want to consider letting NuGet host it.

For a cool and practical example, we created a network shared folder on our build server.  Every time the package builds, we have a nant script that packs and sends the package to the shared folder.  Voila!  NuGet now knows of the new version.

It’s worth mentioning that all of your .nupkg files do NOT have to be in the same folder.  You can set up your folder structure however you’d like, and NuGet will find everything just fine.

For example, our package source has a folder for each package:

\\MY-SERVER\SharedFolderName
    \PackageA
        PackageA.1.0.0.0.nupkg
        PackageA.1.1.0.0.nupkg
        PackageA.1.2.0.0.nupkg
    \PackageB
        etc.

 
1 Comment

Posted by on September 24, 2013 in C#, NuGet, Visual Studio Tricks

 

Model binding a collection with MVC and .NET 2.0

After about 3 hours of frustrating debugging, I came across a quirk/bug when using:

  • MVC
  • .NET 2.0 / 3.5
  • Model binding a collection

Imagine you have a collection of, say User objects.  And you would like to bind that collection to your view, but you only want to display some of the users.  For example, only admin users.  Your view would look something like this..

for (int i=0; i < Model.MyUsers.Count; i++)
{
    User user = Model.MyUsers[i];

    if(user.IsAdmin)
    {
        @Html.EditorFor(user)
    }
}

Now in .NET 4.0, your collection of “admin” users automatically gets bound to a collection in your controller. However, if you run your MVC application on .NET 2.0 framework (which includes 3.5 applications), your model binding will break once it gets to your controller (specifically, your MyUsers collection will be null)!

Why?

MVC uses an index notation in the name attribute of an html element to perform model binding when the request is submitted.  You can inspect the DOM to see this.

Let’s say you have a collection of three User objects, that you render into a <ul>, where each <li> contains a text box that allows someone to edit each user’s FirstName.  MVC will render the following HTML.

<ul>
    <li>
        <input type="textbox" name="MyUsers[0].FirstName" id="MyUsers_0_FirstName" value="Peter" />
    </li>
    <li>
        <input type="textbox" name="MyUsers[0].FirstName" id="MyUsers_0_FirstName" value="Brian" />
    </li>
    <li>
        <input type="textbox" name="MyUsers[0].FirstName" id="MyUsers_0_FirstName" value="Stewie" />
    </li>
</ul>

If you wanted to exclude “Peter” for some reason (i.e. he’s not an “admin” user) MVC will render HTML with Brian’s and Stewie’s objects indexed by 0 and 1, respectively. And when it binds on the request, your controller will receive a collection containing only two objects (Brian and Stewie).

However, .NET 2.0 does this a little differently. It will actually render the Brian and Stewie objects indexed by 1 and 2 (because that is their index in the original, non-filtered collection).

This makes model binding break on the request. Your controller will have a null collection!

The Solution

Upgrade to 4.0! (no, just kidding, I know this isn’t always possible). If you can’t run on 4.0, and you need a work-around, you can manually manipulate the HTML field name that MVC generates for your collection:

for (int i=0; i < Model.MyUsers; i++)
{
    int renderedUserCounter = 0;

    User user = Model.MyUsers[i];

    if(user.IsAdmin)
    {
        string htmlFieldName = string.Form("MyUsers[{0}]", renderedUserCounter);
        renderedUserCounter++;

        @Html.EditorFor(m => Model.MyUsers[i])
    }
}
 
Leave a comment

Posted by on August 16, 2012 in ASP.NET MVC, C#

 

Unit Testing, Extension Methods, and Efficiency.. Oh, my!

Improving unit testing, and use some sleek OOP too.

Let’s say that we want to test a call to a basic stored procedure, where @ClientID is required.

EXEC MYDB.MYSCHEMA.GetClients @ClientID = 10001

Now we want to test the database call in a unit test.  If we don’t pass in @ClientID, we should expect a SqlException, right?  So let’s test that.

// assign
int? testClientID = null;
bool missingClientIDErrorOccurred = false;

// act
try
{
MyDataAccess.GetClients(testClientID); 
}
catch (SqlException)
{
missingClientIDErrorOccurred = true;
}

// assert
Assert.IsTrue(missingClientIDErrorOccurred);

All looks good, right?  We expect a SqlException that says something like “Procedure X expects parameter Y, which was not supplied” (or something close to it).

But what happens if any other SqlException occurs?  Our test will pass.  Oops.  Can we narrow down our catch statement?  Absolutely.  We can find out if the SqlException caught is, in fact, caused by our missing @ClientID parameter by just checking the Message property of the exception.

catch (SqlException e)
{
	missingClientIDErrorOccurred = e.Message
	   .Contains("expects parameter '@ClientID', which was not supplied.");
}

Gravy. Now our test is just that much more accurate, and we shouldn’t have to worry later about incorrect test results. But wait… as OO programmers we like to be efficient, and hard-coding message strings is an obvious code-smell. Let’s improve it using extension methods.

public static bool CausedByMissingParameter(this SqlException exception, string missingParameterName)
{
	string missingParameterErrorMessage = 
	   string.Format(
	   	   "expects parameter '{0}', which was not supplied.", 
	   	   missingParameterName);
       return exception.Message.Contains(missingParameterErrorMessage);
}

Perfect, now we’re good to go. And of course we can reuse this extension method every time we want to write a similar test. Efficiency win. Now, the finish code looks pretty sleek and simple.

//act
try
{
	MyDataAccess.GetClients(testClientID); 
}
	catch (SqlException e)
{
	missingClientIDErrorOccurred = e.CausedByMissingParameter("@CommentID");
}
 
Leave a comment

Posted by on January 30, 2012 in ASP.NET MVC, C#, Unit Testing

 
 
Follow

Get every new post delivered to your Inbox.