You can code it, I can help!

Nuget Gotcha: Avoid Storing Packages in the Repository

It's been a while since Nuget project was released. Since the project birth I've been watching closely to see when would be a good opportunity to start using it for my projects and recommend using it for my clients. Basically, the Nuget project solves dependency management for all your .NET projects. That means that you don't need to search any more for libraries that you need to use like NHibernate or nUnit and just install them from a centralized server.

The path to Nuget

So far I've been using Rake for all my builds and I'm super happy with it. Using a DSL specifically designed for building projects is a great advantage, Ruby gives you lots of flexibility and the Albacore gem is the cherry on top. One of the many things that I like about the Ruby world is gem + bundler combination. For .NET projects I've been using also noodle to copy the dependencies to my local folder (usually called lib). However not everything is ponies and rainbows:
  • Ruby based solutions are not always well received in .NET project (no matter how good they are)
  • Not many developers publish their libraries / frameworks
  • Creating gems with .NET assemblies is discouraged since Nuget was born
All this reasons plus the fact that the .NET community was embracing the idea of package management using Nuget make me consider it as a great option. However one thing was keeping me from doing the change, and that is the ability of reading a configuration file and use it to download all dependencies (very similar to what Bundler does). And that was it.... Until a couple of days ago....

Nuget Adoption

Last week I say a tweet by @davidebbo saying that Nuget supports now reading from a config file! Why is that so important? Because I don't want to store my dependencies in the repository any more! The assemblies that we use in a project usually don't change until we update a newer version. What's the point of storing them with our code if we can use just a reference to them and download them at our leisure? It takes way less space to store our repositories and updating the packages quite easier because you just change the references and the configuration file, and that's it, everyone gets them. Also imagine sharing in your company all the internal assemblies by publishing them to a local Nuget server instead of having a share drive or similar.  Update the version whenever you want! No more versioning dependencies nightmares! And everything is treated the same way, they are all packages! So I installed latest version of Nuget (following the link above) and started the conversion:

Step 1: Changing the References

Open your .sln file, remove all your references and add them again by doing right click + Add Package Reference. That would accomplish the following:
  • Find the reference in the package server
  • Install it to a local package folder (usually called Packages)
  • Write a config file with the dependency installed (in the same folder as the project)

Step 2: Modify the Rakefile

I need dependencies in order to build, so I need to make sure that before building all my dependencies are satisfied, to do so I modified the task setup:dep to do the following: [sourcecode language="ruby"] namespace :setup do desc "Setup dependencies for nuget packages" task :dep do FileList["**/packages.config"].each do |file| sh "nuget install #{file} /OutputDirectory Packages" end end end [/sourcecode] And I need to make sure this happens every time before building, so I need a dependency in the build task (remember that I'm using Albacore for the msbuild tasks). [sourcecode language="ruby"] desc "Build the project" msbuild :all, [:config] => [:setup] do |msb, args| msb.properties :configuration => args[:config] || : Debug msb.targets :Build msb.solution = solution_file end [/sourcecode]

Step 3: Enjoy!

That's it! Super easy! If you want to check the code please go to github and download it.