For those of you who have been hiding under a rock for the last few days, NuPack is a Microsoft sponsored package management system along the lines of Ruby Gems. As anyone who’s tried to use open source software on a .NET project will know, package management, or lack of it, has been a huge problem. Having a standard system that OSS developers can target and a central recognised repository of software will have a major impact on the adoption of OSS in the .NET world.
Make no mistake, this is revolutionary. It’s the difference between right-clicking on references in VS to install an OSS library and the huge PITA that getting source, building, resolving dependencies, etc has been up to now. It makes it orders of magnitude easier.
So, eager to have a play with this shiny new toy, I quickly installed the CTP and fired it up. Looking at the list of packages, I was initially disappointed to see that the latest Castle Windsor release, 2.5.1, wasn’t there. Never mind, I thought, this is a perfect excuse to dig around and see how it works.
Let’s build a new NuPack package for Windsor 2.51.
Castle Windsor has a dependency on Castle.Core, so I need to create a package for that too. Castle.Core also has dependencies on log4net and NLog. So I created a directory structure like this:
In the Castle.Core directory goes the Castle.Core.nuspec file. It’s a simple XML file that describes the package. I just copied the version from the NuPack source and changed the version number, note the dependencies list:
<?xml version="1.0" encoding="utf-8"?> <package> <metadata> <id>Castle.Core</id> <version>2.5.1</version> <authors> <author>Jonathon Rossi & Krzysztof Kozmic</author> </authors> <description>Core of the castle project</description> <language>en-US</language> </metadata> <dependencies> <dependency id="log4net" /> <dependency id="NLog" minversion="1.0" /> </dependencies> </package>
In the lib directory under Castle.Core we put the Castle.Core.dll downloaded from the Castle project website. We do the same for Castle.Ioc, here’s the Castle.Ioc.nuspec file, including the dependency on our new Castle.Core 2.5.1:
<?xml version="1.0" encoding="utf-8"?> <package> <metadata> <id>Castle.Ioc</id> <version>2.5.1</version> <authors> <author>Ayende Rahien</author> </authors> <description>Castle Project ... </description> <language>en-US</language> </metadata> <dependencies> <dependency id="Castle.Core" version="2.5.1" /> </dependencies> </package>
We pop the Castle.Windsor.dll assembly in the lib folder. For log4net and NLog I just copied the existing nuspec files and assemblies from the NuPack source.
The next job is to run nupack.exe against the nuspec files. This packs up the assemblies and the nuspec file into a single nupkg binary file:
Open the Package Manager Console in Visual Studio and point it at our local nupkg files rather than the default remote repository:
Now we can install our new packages:
Note deliberate mistake :)
When you install the packages, NuPack adds a reference to them to your project:
It also creates a packages.config file:
<?xml version="1.0" encoding="utf-8"?> <packages> <package id="NLog" version="1.0" /> <package id="log4net" version="1.2.1" /> <package id="Castle.Core" version="2.5.1" /> <package id="Castle.Ioc" version="2.5.1" /> </packages>
One thing that confused me for a while is that NuPack caches the packages list while your solution is open. When I deleted all the references, the assemblies and the packages.config file it still insisted that: ‘Mike.Spikes already has a reference to 'log4net 1.2.1'’. Closing and opening the solution refreshed the cache and fixed the problem.
So there we have it. NuPack is very cool and the fact that it only took me a couple of hours this afternoon to go from zero to building my own packages shows how easy it is. You need to learn how to use it, it’s going to be ubiquitous in .NET development very soon.