You probably heard about NuGet (formally known as NuPack), an open source package management system for the .NET from Microsoft. Jeff Kwak, who works with me at Ultimate Software, recently wrote a nice post about how to create a NuGet Pakage. Jeff’s article inspired me to create a package for my own open source project, SystemWrapper. In this post I want to describe step by step how I did it.
Step 1: Create a NuSpec file.
NuSpec file is an xml file that contains the metadata for a package. I’ll try to describe every field of NuSpec format with an example.
In this first step we’ll going to use the minimum set of fields.
|id||The identifier for the package. It used as a partial name of the package.|
|version||The package version. Also used as a partial name of the package.|
|authors||Author name. Use a comma to separate multiple authors.|
|description||You know what it is.|
<package> <metadata> <id>SystemWrapper</id> <version>0.3.5.0</version> <authors>Vadim Kreynin</authors> <description> SystemWrapper is a library that wraps .NET classes for system resources like System.IO.FileInfo, System.Reflection.Assembly, and many other classes so you can easily mock them. </description> </metadata> </package>
I named the xml SystemWrapper.nuspec. I believe that it is a good logical name for NuSpec file.
One of the way to add a package is to use Add Library Package Reference dialog. I’ll talk more about adding a package and Add Library Package Reference dialog later in this article but for now I want to show where NuSpec fields a re used. Bellow is the image that describes where above NuSpec metadata elements used in the dialog.
Step 2: Build the package.
First you need to download NuGet.exe command line tool.
Now when we have NuGet.exe, we are ready to create our SystemWrapper NuGet package. Fire up your Command Console and type the following line.
NuGet.exe pack SystemWrapper.nuspec
If everything runs at it supposed to, you should see systemwrapper.0.3.5.0.nupkg file in your Windows Explorer.
As you can see the name of the file is [id].[version].nupkg. id and version from our NuSpec file.
Step 3: Publish the package.
To release System Wrapper to the world we need to contribute to NuGet packages on CodePlex. In this example I’m going to show how to host System Wrapper NuGet package locally. You can follow this technic to host packages for your company. I learned how to host NuGet packages locally from a great Phil Haack’s post.
First, I create a directory for my packages. It has an original name ‘packages’.
Next, we need to add another package source. Out of the box you should have only one package source which named ‘NuGet official package source’. We are going to create another package source and I’m going to call mine ‘Vadim’s package source’. I think that this is going to cement my legacy.
In order to add a package source in Visual Studio we need to go to Tools –> Options. Inside the option dialog box select Package Manager and enter values for Name and Source and press Add button and then OK to close the Options dialog.
You also can get to this dialog by pressing Settings button in Add Library Package Reference dialog, which is the first image of this post. The button located in the lower left corner of the dialog.
Step 4: Find the package in Visual Studio.
There are two ways we can browse for our package. One way is using Package Manager Console which is Powershell based. Another one is Add Library Package Reference dialog that I mentioned earlier.
After console is loaded, we need to select our package source. Just pick it from the Package source drop down box. In my case it’s “Vadim’s package source”. Next, type List-Package at PM> prompt. See the result bellow.
I don’t know why I cannot see my description in Package Manager Console. It shows fine in Add Library Package Reference dialog. Let me know if you have an answer for me.
Now let me show how you can browse for the package using Add Library Package Reference dialog. The way I do it is just right click on References in the project to see my add options. Select “Add Library Package Reference…” to display the dialog. The dialog has three panels. The first panel has three sections: Installed packages, Online, and Updates. “Installed packages” shows the package that installed for specific project. The second one “Online” shows packages that are available. We want to chose this option. Select your package source. The third option is updates.
The second panel shows the list of packages. The third panel shows details of the selected package.
It doesn’t make scenes for us to install the package at the moment because we only describe the package but doesn’t add any libraries to the project.
Step 5: Add SystemWrapper.dll to the package.
Our goal is to add SystemWrapper to the project. It means that we need to add assembly reference to SystemWrapper.dll. It’s very easy to do, we just need to add files element to our NuSpec file. files element must be on the same level as metadata element.
Here’s a fragment that we add to NuSpec metadata:
<files> <file src="SystemWrapper\bin\Release\*.dll" target="lib" /> </files>
file element has two attributes src and target. I just want to let you know that src is a path that relative to the nuspec file. Our target attribute has a value ‘lib’, it means that dlls under SystemWrapper\bin\Release will become assembly references on install. In our case it’s going to be only one dll. You can get more details on your own by reading the NuSpec File Element Specification.
Here’s the complete NuSpec file:
<package> <metadata> <id>SystemWrapper</id> <version>0.3.5.0</version> <authors>Vadim Kreynin</authors> <description> SystemWrapper is a library that wraps .NET classes for system resources like System.IO.FileInfo, System.Reflection.Assembly, and many other classes so you can easily mock them. </description> </metadata> <files> <file src="SystemWrapper\bin\Release\*.dll" target="lib" /> </files> </package>
After we updated NuSpec file, we need to repeat step 2 (Build the package).
Step 6: Install the package.
Once again you can install either from Package Manager Console or from Add Library Package Reference dialog. It’s strait forward to install it from Add Library Package Reference dialog, you just press the Install button. After the installation, I have SystemWrapper in my Installed packages. I can easily uninstall it by pressing the Uninstall button. How easy is that? Also if I look in Online section, I can see that instead of an Install button there’s a green check mark for my package.
In Package Manager Console I just type Install-Package SystemWrapper at PM> prompt.
PM> Install-Package SystemWrapper
Successfully installed 'SystemWrapper 0.3.5.0'
Successfully added 'SystemWrapper 0.3.5.0' to PackageObjectLibrary
You can uninstall the package by typing Uninstall-Package SystemWrapper.
For more details check out Package Manager Console Commands.
Step 7: Display more information about the package.
When developers browse for packages, they probably would like to more information about a package than just a description. Adding projectUrl element to NuSpec file will point users to the resource with more details.
Here’s an example for System Wrapper:
You might also want to add a link to your license terms. Once again you need to add another field to the NuSpec file. This time we need to add licenseUrl. If you don’t want a developer to install your package unless she accepts the license terms, than you need to add requireLicenseAcceptance element. The xml might looks like this:
When a user tries to install the package, she will see a dialog similar to the one bellow:
You also can specify your own icon instead of default blue NuGet icon that appears in Add Package Reference dialog . The element for an icon is iconUrl. The icon should be a 32×32 pixel PNG file with a transparent background.
The complete NuSpec file might look something like that:
<package> <metadata> <id>SystemWrapper</id> <version>0.3.5.0</version> <title>System Wrapper</title> <authors>Vadim Kreynin</authors> <description> SystemWrapper is a library that wraps .NET classes for system resources like System.IO.FileInfo, System.Reflection.Assembly, and many other classes so you can easily mock them. </description> <projectUrl>http://systemwrapper.codeplex.com/</projectUrl> <iconUrl>http://systemwrapper.codeplex.com/32_button_green.png</iconUrl> <licenseUrl>http://systemwrapper.codeplex.com/license</licenseUrl> </metadata> <files> <file src="SystemWrapper\bin\Release\*.dll" target="lib" /> </files> </package>
I know that I didn’t talk about dependencies or modifying config files at all. I just try to give a simple example to follow. I hope that it can help you to get started with NuGet. Here’s some references I would recommend for you to read:
- Offical NuGet Documentation
- Hosting Your Own Locan and Remote NuGet Feeds – by Phil Haack.
- NuGet CTP 2 changes – by Phil Haack.
- Creating a NuGet Package – by Jeff Kwak.
- Introduction to NuGet – by Scott Hanselman.