Nancy 0.12 released!
I am really happy to announce that we’ve released Nancy 0.12 into the “public”. To be fair all of our work is always in the public, but now we’ve actually slapped a new version on it and put it up on Nuget for easy access!
It took a bit longer than I would have liked, but it’s amazing with a little bit of summer and a month off from work will make time pass incredibly fast! There is an old Swedish proverb that says “"He who waits for something good never waits too long." which basically means “something good is worth waiting for” and I’d like to think it very much applies to this release.
It’s a massive release with 20 authors squeezing in 237 commits and helping with closing of 64 work items. Thank you, so much, to all that have contributed! You can find the full commit log here and the work items here. There is no way I can walk you through all 64 work items, that makes up this release, so I’ll give you a short highlight reel.
Content Negotiation – the star of the release
Getting support for Content Negotiation, into Nancy for this release, was the big thing for me and @Grumpydev http://twitter.com/grumpydev and we really went into this with a clean slate and quite a lot of questions, mostly on how to preserve the Nancy syntax and make it really Super-Duper-Happy-Path.
I am happy to say that the syntax stayed exactly the same, it just got more powerful! The key difference is that you are no longer restricted to returning a Response object (or any of the types that are implicitly cast to one), but you can return what-ever-you-want. Booya!
If you return anything else than a Response object, the response will be subject to take part in content negotiation with the client that sent in the request. We provide a syntex to help you control the behavior, on a per-route level (should you need to) and application wide conventions.
Content Negotiation is built around the new IResponseProcessor interface, which is what you implement to add support for a new media range or model type, and Nancy will automatically detect it and wire it up for you!
Keep an eye on our Wiki for more detailed information, on Contente Negotiation, that should be coming up very soon. If you want to jump right in, you can either have a look at the Nancy.Demo.Hosting.Aspnet project, in our solution, and more specifically the /negotiated route.
You can also watch the aspConf talk, by Christian Horsdal on “The Lightweight Approach to Building Web Based APIs with .Net” where he shows of the content negotiation bits. The source code for his sample can be found at https://github.com/horsdal/Restbucks-on-Nancy
A new, out-of-the-box, authentication method has been added by Byron Sommardahl and can be installed with the Nancy.Authentication.Stateless Nuget. For a demo, have a look at the Nancy.Demo.Authentication.Stateless project, in our main solution.
Emil Cardell also contributed ISerializer and IBodyDeserializer implementations for JSON.NET, which can be installed using the Nancy.Serialization.JsonNet nuget package. Once installed it will automatically be picked up by Nancy.
No more NDjango out of the box
In 0.11 we removed it from the Mono Build Configurations and still had it build for Windows configurations. In 0.12 we made the decision to no longer support NDjango for a couple of reasons.
The development on the NDjango engine has been stale for quite a while now. Because of the fact that it’s built on F# has also always been a bit of a pain for our Mono support and with the release of .NET 4.5 and Windows 8 it’s added even more headaches that Grumpydev blogged about. If you wish to use NDjango then you can still do that.
It’s just an implementation of our IViewEngine interface (which is really light) so you can dig out the source code from our repository and just stick it in your project. You can even create and maintain your own Nuget for it, all we’re saying is that we won’t be the ones maintaining an NDjango engine anymore.
Lots of love for Nancy.Testing
For this release we gave the Nancy.Testing package some needed love. The whole list of changes that were introduced can be found here but I wanted to give highlight a couple of things
Convention based loading – Because of the way that .NET loads (or rather not loads) assemblies, that aren’t explicitly used, into the AppDomain, Nancy.Testing sometimes could not find these types. For instance if you test assembly A, referenced application assembly B, which in turn referenced helper assembly C then C will not be loaded into the application domain of the tests, unless one or more types from C where explicitly referenced from test assembly A. This is not a Nancy thing, but a .NET thing.
What we did was to have the ConfigurableBootstrapper help you get around this, but taking the name of the test assembly, attempting to remove “test”, “tests”, “specifications”, “specs”, “unittests” from the end of the name and make sure it, and all assemblies it references are loaded into the application domain.
This is not going to cover all scenarios, but it should cover the majority of them. As always, the naming conventions can be modified by setting the static TestAssemblySuffixes on the ConfigurableBootstrapper
Removed XUnit dependency – Before, some of our assertions were using xunit assertions internally, forcing a dependency on XUnit no matter if your tests were written in a different test framework or not. We’ve now removed this completely by adding our own assertions.
Now using CsQuery instead of HtmlAgilityPack – Our assertion helpers, that lets you assert on the HTML that is returned by a view, was previously using HtmlAgilityPack under the hood. We decided to swap over to CsQuery, which is a C# implementation of the jQuery selector syntax. Mostly because of some issues we were having, plus CsQuery has a cooler syntax. This should not have an impact on your test.
Auto-registration is now disabled by default – If you were using the ConfigurableBootstrapper, before 0.12, then it would use auto-registration, by default, to scan and register types into the container. You had the option to disable it to give you a (potentially huge) performance boots and make the tests more explicit. Starting with this release we flipped the behavior so that auto-registration is always turned of and you have to explicitly enable it with the EnableAutoRegistration option. We hope that it will help make the intent of the tests even clearer and at the same time make sure they are executed as fast as possible.
IStartup gets a new identity
You might have used the IStartup interface to perform a code action when the application started, for the first time, or to register some dependencies in the container. Looking at it, we thought it was a violation of the Single Responsibility Principle and decided to split the two actions into separate interfaces.
There ended up being IApplicationStartup for startup actions and IApplicationRegistrations for dependency registrations. You could always implement your own IStartup interface that simply inherited from IApplicationStartup and IApplicationRegistrations and the rest of your code could be left unchanged.
Razor error page
If you’ve ever encountered the Razor error page, that you get when there is an error in your view, then you know it does not offer much assistance to resolving the problem. We pimped the page so it’s now damn useful and should help you pinpoint your issue in seconds. Have a look your self!
Now that’s what I call awesometastic!
Yep, unfortunately, there are some of those too. As always we try to keep them as few as possible and hopefully most of them won’t have an impact on your application. For a full list of the breaking changes, take a look at the list
Things to come
Looks like there are a huge list of cool things coming down the pipe. For the next release (which should happen within the month) we will be going over the 30+ open pull requests and pull in the ones we find awesome and suitable.
Looking a bit further down the pipe we have async routes, improved session and cache support which will let you hook up any provider you want (how about memcache, redis or a database?) very easily?!