Remember when I told you about the awesomeness that is NuGet? No?! Well go read about it silly! I only told you half the story. Consuming packages in your projects is very helpful for most developers. Why reinvent the wheel? However, once you create a library why not share it with others? This article will explain how to go about publish a package to a NuGet feed. I will discuss what you need to prepare your library for package style deployment. Covering the actual packaging will follow the preparation phase. The last item I will cover will be versioning.
Turning Your Library Into a Package
The key thing you want to do when publishing your library as a NuGet package is to distill the library down to its key components. If you’ve been using NuGet to consume other libraries during development one of the first things you’ll want to do is note down what versions you’ve used and then remove those DLLs from your output. Essentially your first task is to distill your output to be the content that you are providing. Once you have cleaned your output to be only those files which you produce it is time to start classifying them into different file types. NuGet defines these types of files in its package structure:
- Folder named “content” within the package
- Files placed here will be added to the root of the project which is consuming your library. If your library has a configuration file or some other file which must become part of the consuming project it should be placed in this folder.
- Folder named “lib” within the package
- All of the DLLs which will become references in the consuming project should be contained within the library folder.
- Folder named “tools” within the package
- Tools are powershell scripts which are run when the package is imported (installed – install.ps1) or removed (uninstalled – uninstall.ps1) from a project.
- Folder named “src” within the package
- If you’re distributing source code with your library it can be included in the source folder.
Within each folder you can add an additional folder to target specific .NET frameworks. The target column of the following table will tell you where to add the files.
|.NET 3.5||net35||Just using ’35’ also works.|
|.NET 4.0||net40||Just using ’40’ also works.|
|.NET 4.0 Client Profile||net40-client|
|.NET 4.0 Full Profile||net40-full||Requires full .NET profile|
|.NET 4.0 Compact Framework||net40-cf||net40-compactframework also works.|
|.NET Micro Framework||netmf|
|Windows Phone 7.0||sl3-wp|
|wp7||Only in NuGet 2.1+|
|Windows Phone 7.1 (Mango)||sl4-windowsphone71|
|wp71||Only in NuGet 2.1+|
|Windows Phone 8||windowsphone8||Only in NuGet 2.1+|
|windows8||Only in NuGet 2.1+|
|Portable class library for Windows Store apps and .NET 4.5||portable-windows8+net45||Only in NuGet 2.1+|
|Portable class library for Windows Store apps, Silverlight 4.0 and Windows Phone 7.1||portable-sl4+wp71+windows8||Only in NuGet 2.1+|
Building Your Package
Now if you’ve done the above and moved your output files into a temporary structure as I’ve defined then you will be able to easily build your package. NuGet provides the ability to build a package using the command line or you can use a GUI. Even though I love my Ubuntu I still trend towards GUI interfaces than using a CLI. NuGet provides a ClickOnce GUI interface called NuGet Package Explorer. It can build downloaded by clicking here. I will be using Package Explorer to discuss the package building process. After following the ClickOnce application install information you can launch Package Explorer and click File -> New to create a new package. You should be greated with a screen similar to this:
The right pane contains information regarding the package’s metadata and the right side is the structure of the package’s files. Start off by clicking the “edit” toolbar button on the Package metadata pane, the icon furthest to the left.
The bolded labels indicate files that are required to be filled out. The Id section is a unique name for your package. You should name it so that it has some reference to your library name. The Version field is important. It will allow those who consume the package to decide which versions they wish to use. Authors should be your name. The Description field should contain a brief description of what your package contains. Scrolling down the Package metadata pane you will find a button titled Edit dependencies. This button will allow you to setup the dependencies your package needs in order to function. Earlier I mentioned that when setting up your package files that you should remove any files which are added through a reference of a NuGet package you used during development of your package. The reason this was done is that in the dependencies popup you can define those packages which you used during the development of your library. This makes your package file as small as possible and, if you define your dependencies correctly, you are able to dictate which versions of those consumed packages are able to be used with your end library.
Using the Package Dependency Editor you can specify the packages that will be installed alongside your package. Packages you would want to include here would be any package you consumed during your creation of your library. The first textbox field will be the package’s ID field and the second will be the version information. Refer to this link for how versions can be specified. Clicking the icon which in the above screenshot has the mouse cursor above it will launch a window which will enable you to search a package feed of your choice. Once you have all your metadata set up in the right pane you can click the checkbox that is in the toolbar at the top of the pane. This is probably a good point to stop and save your work.
Setting Up the Package Structure
Defining the metadata allows you to define how people will find your package, define dependencies, etc. but what to actually have a useful package that delivers your library you’ll need to define your package structure. The right pane of the main menu is where you will be defining the package contents. If you refer back to the section where we discussed cleaning up your library outputs and have already placed your files into the corresponding lib, content, tools, and src directories you’re ahead of the game. If not don’t fret. The Package Explorer tool makes creating the folder structure for your package very easy.
Right clicking in the Package contents area will give you a drop down of all the main types of folders which can be created. Select what you want to add and the folder will show up in the pane. You can then right click on the folder to keep adding folders in a directory tree manner. Under all the folders except src you can specify the .NET version to filter what parts of the package will be deployed for projects using different versions of .NET.
As you can see in the above picture you can create a pretty detailed package. Each of the folders under the main sections detail which .NET version a project must use to get the contents of the folder. In the case of the content folder it has no .NET version specified. This means that all projects will get these files. You can drag and drop your files into the appropriate folders in the editor. You can also right click on a folder and select Add Existing Item… or Add Existing Directory to find and include items into the package structure.
Almost Ready To Publish
Once you’ve defined your metadata and built your package contents in the Package Explorer program you are ready to publish to a NuGet feed. It’s best to stop here and save your package locally so you’ll have a local backup.
To publish you’ll need an API key. Signing up at NuGet.org will allow you to post to the public NuGet feed. Once you’ve verified your email address you’ll be issued an API key. The image below shows the Publish Package dialog box that shows when you are ready to publish to the public feed. Once you place your API key into the Publish key field and hit Publish your package will be live in seconds.
In my case I’ve setup an internal version of the NuGet gallery inside our corporate intranet. This allows all of our teams to publish their libraries to a central server within the company so that other teams can consume them. Our projects can consume both public NuGet packages from the main feed and from our internal feed. This enables us to have all the benefits of NuGet without exposing our company’s intellectual property to the outside world. I highly suggest looking at setting up your own NuGet gallery in your company so you can help your developers with code reuse!