Combinatorics in .NET - Part II - Creating a Nuget Package
This is part 2 of a 2 part post on Combinatorics in .Net
The solution is publicly available on github; https://github.com/eoincampbell/combinatorics
The library can be added to any .NET Soution via Nuget; https://nuget.org/packages/Combinatorics
In the last post we looked at the Combinatorics Library, a .NET Assembly which provides Combinatoric generation capabilities to your .NET Applications. Now lets look at bundling up that solution & deploying the package to Nuget. Nuget is an online .NET Package Repository & associated Visual Studio extension that makes it easy to manage external assemblies in your projects. Developers who build 3rd party libraries or tools can create a NuGet package and store the package in a NuGet repository. Other developers can then browse the repository (online or with Visual Studio) and add references to those 3rd party tools & libraries.
You can read more about Nuget here.
Nuget Packages support bundling different versions of an assembly based on different target frameworks and different dependencies. Since the combinatorics libraries rely only on .NET 2.0 Generics one project within the solution is set to target .NET Framework 2.0 as a minimum. A second project currently contains the same Combinatorics functionality but is set up as a new "Portable Class Library" Project format. This project type allows you to specify the minimum frame work requirements for the .NET Framework, Silverlight, Windows RT & the Xbox Libraries. The Combinatorics.net40 project targets .NET4.0, Silverlight 4 & WinRT and will allow for improvement of the library using BCL functionality available in those frameworks.
Creating a Nuspec
In order to deploy an assembly (or set of assemblies) as a NugetPackage, you need to first fill out a Nuspec file for that deployment. Think of a Nuspec as a sort of manifest or metadata file that contains information about the package. First of all we generated a template specification file using the following command
nuget spec Combinatorics.dll
<?xml version="1.0"?> <package > <metadata> <id>Combinatorics</id> <version>22.214.171.124</version> <title>Combinatorics Library for .NET</title> <authors>Adrian Akison, Eoin Campbell</authors> <owners>Eoin Campbell</owners> <licenseUrl>https://github.com/eoincampbell/combinatorics/blob/master/LICENCE</licenseUrl> <projectUrl>https://github.com/eoincampbell/combinatorics</projectUrl> <iconUrl>https://raw.github.com/eoincampbell/combinatorics/master/combinatorics.png</iconUrl> <requireLicenseAcceptance>false</requireLicenseAcceptance> <summary>A Combinatorics Library for Combinations, Permutations &amp; Variations in .NET</summary> <description>A Combinatorics Library providing Generic IEnumerable classes ...</description> <releaseNotes>Notes</releaseNotes> <copyright>Copyright © 2012</copyright> <tags>Combinatorics Combination Permutation Variation .NET Library</tags> </metadata> </package>
Once the specification file was created, it was moved to a "preparation folder". Nuget supports spec'ing and packaging an assembly direcltly from the Project directory & csproj files, but if you want to do your own multi-framework targetting you need to manage things a little differently. The "Nuget" folder under the solution root contains the Spec & also contains the required Lib folder structure for the different versions of the assemblies.
You can read more about the internal organipackage
Building & Deploying the Package
Building the Solutions & Deploying the package to nuget is handled by 2 batch files in the solution root.
First Build.bat runs, builds both solutions, cleans out the old Nuget Package Lib structure & copies the new assemblies to the newly created directory structure.
@echo off devenv Combinatorics.sln /Clean devenv Combinatorics.sln /Build Debug if exist Nuget\lib rmdir /S /Q Nuget\lib mkdir Nuget\lib mkdir Nuget\lib\net20 mkdir Nuget\lib\net40 mkdir Nuget\lib\sl40 copy "Combinatorics.Net20\bin\*.dll" "Nuget\lib\net20\" copy "Combinatorics.Net20\bin\*.pdb" "Nuget\lib\net20\" copy "Combinatorics.Net20\bin\*.xml" "Nuget\lib\net20\" copy "Combinatorics.Net40\bin\*.dll" "Nuget\lib\net40\" copy "Combinatorics.Net40\bin\*.pdb" "Nuget\lib\net40\" copy "Combinatorics.Net40\bin\*.xml" "Nuget\lib\net40\" copy "Combinatorics.Net40\bin\*.dll" "Nuget\lib\sl40\" copy "Combinatorics.Net40\bin\*.pdb" "Nuget\lib\sl40\" copy "Combinatorics.Net40\bin\*.xml" "Nuget\lib\sl40\"
Next the nupkg package is created & deployed to Nuget using the PushToNuget.bat BatchFile.
@echo off nuget pack Nuget\Combinatorics.nuspec nuget push %1