What on earth has happened to NuGet?

Nuget3

After several months away from NuGet, I had to use it again recently in VS2015. I’m completely and utterly gobsmacked at how poor the current experience is. It’s confusing, inconsistent and hard to use. Worse than that, it enables workflows that should never, ever be permitted within a package management system.

First experiences with the NuGet dialog

When I first saw the previews of VS2015, I thought that the non-modal, integrated dialog into VS would be a good thing. Unfortunately, it suffers from not making it clear enough what the workflow is. You’re bombarded with dropdowns that sometimes have only one option in them, search boxes in non-intuitive positions, installation options that you don’t want to see etc.

Let’s start by adding a package to a solution. This is a common task so should be as easy as possible. Here I’m adding my old friend Unity Automapper to two projects in a solution (note that I’ve deliberately downgraded to an earlier version of the Automapper) :-

nuget1Why so many options? Why a dropdown for Action that only has one item in it? What does the “Show All” checkbox do – looks like nothing to me at this point. Are there projects hidden from the list? Why?

Working with packages

Next let’s try to do something to the package e.g. uninstall or update. You go to Manage Packages for Solution. You don’t see the packages that you’ve already – instead, you see all packages available, ordered by (I assume) most popular download. My installed package is nowhere to be seen. How do I find installed packages only? Oh. You have to click “Filter” and then select “Installed”. That’s not what I thought of doing when I selected the menu option. I thought it would just show it to me – it took me a good few seconds to realise what had happened!

Also notice that the default dependency behaviour is “lowest” – I don’t like this. Highest should be the default, or maybe Highest Minor. Nine out of ten times you’ll just have to upgrade them all immediately afterwards anyway. Which brings me nicely onto the subject of upgrading NuGet packages…

Upgrading dependencies

So now I’ve found my package, I want to upgrade it. So I choose to manage packages for solution, and change the action from Uninstall to Update. It picks the latest version available (good).

nuget2But then notice in the screenshot above it allows me to uncheck some of the projects within the solution. What?? Why would you want to explicitly upgrade only some of the projects within the solution! I can maybe think of some corner cases, but generally this is a definitely no-no – a recipe for absolute disaster. At best you’ll muddle on with some binding redirects, at worst you’ll get a runtime error at some indeterminate time in the future when you try to call a method that doesn’t exist. What happens if you have a breaking change between the two? Which version will get deployed? Can you be sure? Don’t do this. Ever. I can’t even understand why NuGet offers you as the user to do this.

Even worse, if you choose to update a NuGet dependency at the project level (by e.g. right clicking the references node in VS), VS will upgrade it on that project alone. The other projects that have that dependency will be left untouched. You’ll end up with different versions of a dependency in a solution without you even realising it.

But let’s see what happens if we decide to live dangerously and go ahead anyway. Firstly, NuGet will happily upgrade half our solution and leave the other half in an old state – no warnings of impending doom, no nothing. Your code might work, it might not. Maybe it’s work fine for some weeks, and then you’ll realise that the upgrade has a breaking change, but you only notice this when project A tries to call a method that no longer exists.

The next time you next enter the NuGet panel to work with your dependencies – e.g. to uninstall the dependency, you’ll see the following: –

Nuget3Why is only one of my two projects showing in the list of projects that I want to uninstall? Because it’s filtering it on that specific version of the dependency (1.1.0). I have to choose the version that I want to uninstall. I don’t want that – I just want to uninstall the entire dependency. But no, we have to do it version by version. If we now change the Action to “Update”, the Version dropdown suddenly has a different meaning. It no longer acts as a filter – it’s now stating what version we’ll upgrade to. Instead, you now filter based on the projects checked in the list below. So the meaning of each user control has changed based on the action you’re performing. This is not good UI design.

UI Thoughts

In fact, the UI as a whole is really, really confusing. There are also other issues – it’s slow. You can’t upgrade all projects through the UI yet, so either you have to fall back to the Package Manager console, or upgrade each package one by one. Of course, after you do any single update, the UI reverts back to showing “All” packages which involves loading the top results from NuGet. This takes a few seconds. Then you need to change the dropdown to show “Installed” packages, and start all over again.

Conclusion

I’m really worried having seen the new NuGet now. It’s been in VS2015 for a while – and developers are putting up with this? It’s slow. It’s not a well designed UI – even I can tell that. You don’t feel like you know what is actually going to get deployed. The workflows don’t really work. It’s not good.

And it’s not just the UI that concerns with me NuGet. It’s also the fundamental structure underneath it that is unchanged and needs to be fixed. NuGet should be managing dependencies across an entire solution as the default and ensuring that dependencies across projects are stable. Instead, we have individual package.config files on each project, each with their own versions of each dependency. This is not what you want! As illustrated above, it’s very possible – and in fact quite likely on a larger project – that you’ll quickly end up with dependencies across projects with different versions. I’ve seen it lots of times. You run the risk of getting runtime bugs or crashes, and worse still, ones that might only be identified when you go down a specific code path in your app, probably the day after it goes live.

I was hoping that NuGet in VS2015 would start to address these issues, but unfortunately it seems like a large step backwards at the moment.

Unity Call Handlers released on NuGet


Having worked on this for a while, I’ve now released a set of simple, easy-to-use call handlers for Unity on NuGet. These include Method Logging, Timing, Caching and null argument Validators. I might add to this collection in future – the source code is on GitHub so you have a look through it as you want (or submit some more if you like :-)). If you use it in conjunction with the Unity Automapper, it allows you to very, very easily start getting a pluggable set of classes going with aspects.

You can get the package on NuGet and have a look at the docs on GitHub.

Using Unity Automapper, Step-by-step


Although it’s pretty self-explanatory, I thought that some simple instructions how to use the Unity Automapper might be a good idea anyway.

Installation

If you’re reading this, there’s a good chance you’re coming here from the link in NuGet’s description, in which case you can skip straight to the Usage section below. Otherwise, read on…

  1. Fire up Visual Studio and open your solution.
  2. Open NuGet on the project you wish to perform the Unity registrations on (typically this will be your startup project)
  3. Search for Unity Automapper. NuGet isn’t the best at finding packages so you might have to search for it a bit.
    image
  4. Alternatively you can simply install it via the Package Manager Console with the command.image
  5. That’s it! You’re now ready to start using the AutoMapper!

Usage

This is even easier.

  1. Add a using statement to the top of your source file where you want to perform the registration on.image
  2. Create your Unity Container as normal.
  3. If you have a list of types at compile-time that you wish to use as the source of registrations, simply call the AutomapTypes() method: –image
  4. Alternatively you could just chuck in all the types in e.g. your executing assembly at run-time: –image
  5. If, on the other hand you’re using a more plug-in style architecture where e.g. you want to source your registrations from assemblies that your registration project doesn’t have a reference to, or you want to map concretes that are internal to another assembly etc., you can just provide the assembly names using the AutomapAssemblies() method: –image
  6. So in this example, perhaps we have an interface in our Services assembly e.g. IDataAccess, which is implemented by a class in DataAccess. You can now make the concrete implementation completely private; it’ll simply be found by the mapper and wired up.

That’s it! Either of those calls will perform any mappings that it can find into Unity; you’re now ready to go.

Other features

Here are a few other features that the mapper offers…

  1. If you want to make your data access layer a singleton in Unity, simply mark the interface (not the implementation!) with the [Singleton] attribute (this necessitates referencing the Automapper from that assembly as well).image
  2. If you want to specifically ignore a type from the Automapper – perhaps you have a fake class you sometimes turn on or use in testing etc. rather than when really running – just mark it with the [DoNotMap] attribute.image

That’s pretty much it. Two method calls and two (optional) attributes – not a massive API but hopefully one that saves you some time when using Unity.

Unity Automapper on NuGet


I wrote many, many moons ago about doing auto-mapping in Unity using e.g. reflection etc. instead of resorting to config files etc..

Well I’ve now released, via NuGet, a package that offers exactly that. It’s not the most configurable API but supports what I believe are the most common use-cases for auto registration, allowing you to get up and running in seconds. Just download the package, call a single extension method and off you go.

Features

  • Simple API exposed as extension methods on the Unity Container itself – up and running in seconds
  • Automatically registers multiple types based on interface implementations – no naming conventions required
  • Automatically registers types located across multiple assemblies – perfect for implementing DIP easily without breaking rules of encapsulation

So, if you use Unity, download the package and give it a go – I’d love to hear your feedback (good and bad!).

NuGet, EF4.1 and SQL Compact 4


As I’m waiting around this week for furniture to be delivered to my new abode, I was passing the time today by trying out EF4.1. I thought it’d also be a good opportunity to try out NuGet in order to see how easy it is to download packages + dependencies etc. etc..

So, the test was: Download EF4.1 and SQL Compact 4 with NuGet to allow me to create a simple data model and get some CRUD functionality up on screen in a WPF screen. It failed me.

NuGet itself seems very nice – the ability to easily download packages and their associated dependencies for a VS solution, integrated within the IDE etc. – great stuff; I will definitely use it in future.

Unfortunately, neither the package for EF4.1 nor SQL Compact 4 contains the System.Data.SqlServerCe.Entity.dll, thus as soon as you try to make a connection to a SQL Compact database with EF4.1, your application will crash:

Could not load System.Data.SqlServerCe.Entity.dll. Reinstall SQL Server Compact.

The solution is to manually install SQL Compact 4 from this link. Once done, you should be good to go.

So, a failure for NuGet insofar as the packages supplied did not contain the correct assemblies for what was required – however, NuGet in general seems very impressive and I would recommend you taking a look at it in future.

 

 

UPDATE

There are actually two SQL Compact packages on nuGet. One is simply called SQLServerCompact; the other is called EntityFramework.SqlServerCompact. I had downloaded the former during my attempt described above. If you download the latter package, you will find that you get the .Entity.dll and don’t need to install SQL Compact 4 separately. Not sure that it’s entirely clear though that there are two versions of SQL Compact 4 in nuGet…. one which is “compatible” with EF4 and one which isn’t…