Posterous theme by Cory Watilo

Nancy view cache, now disabled in debug-mode

A quick heads up. In Nancy 0.6.0 we introduced a change that made the application scan, for all available views, and cache them upfront. While this is good for performance, because it reduces view loading time and limits I/O operations, it does pose a slight nuance then you are creating you view.

Because of the cache, each time you made changes to the view template you had to restart the webserver so that the Nancy startup code ran again. A bit of a pain in the sitting area, I agree.

This update is not in the 0.6.0 release it self, not in the NuGet packages. So in order to get a hold of a copy that uses this you will have to either download the latest source code and built it yourself, or grab the latest artifacts from our TeamCity server. 

 

Nancy 0.6.0 saw the light of day

Nancy recently reached version 0.6.0 and was the result of 220 changed files, divided into 126 commits by a total of 12 different authors. That alone is pretty damn awesome if you ask me, but of course we didn’t just make random changes to the code, we did try to add some new cool stuff as well!

The major parts that got some attention in this release were performance, there bootstrapper, the view engines and lots of internal changes that you will only notice if you work with the code.

So let’s dig in an see what we we’ve concocted

Bootstrapper

We are quite proud of the bootstrapping approach we have taken in Nancy. It’s right in the center of everything and helps us implement new functionality with minimal effort but it also helps Nancy users get dependencies into their modules absolutely minimal effort. In the 0.6.0 release we put quite a lot of effort into the bootstrapper code.

Un essence it can be summed up with:

  • A lot cleaner public facing API
  • Makes it easier to implement a custom boostrapper for a different container
  • Reduces friction when adding Nancy functionality moving forwards

View conventions

Prior to 0.6.0 you were pretty limited to where Nancy would look to resolve views to render. In fact you were limited to a folder called views, that had to be in the root of your application. Well that’s now changed into being convention driven instead, with the possibility to modify the conventions yourself.

The default conventions that is shipped with Nancy are

Providing your own is equally as simple. You create a custom boostrapper (that Nancy will find automatically and use) and modify the list (yes, conventions are stored in an IList<Func<string, dynamic, NancyContext>> instance) in what ever way it please you

View caching

Let’s be blunt. View engine were slow in Nancy before we pushed out 0.6.0. Why? Well, for different reasons for different engines, but it all boils down to the fact that views were located and compiled on each and every request. Ya, I know.. slow. But no more! The first thing we did was to have Nancy identify all views that could be rendered (based on the available view engines in your application) and cache them at application startup. This means the file system (or what ever means of storing your views you use) only gets hit once, removing an expensive traversal from the request/response cycle.

The second thing we implemented was a cross-engine view cache. This means that we now cache the compiled, but not initialized, version of a view. Not having to compile the view on each request was huge performance boost. How big you ask? I’ll let you view it with your own eyes.

Benchmark

I know! Pretty impressive, isn’t it. Let me give you some help to understand what you are seeing. The (M) means master branch and (E) means experimental branch. While we were working on this we used a different branch so these benchmarks were taken right before we merged experimental back into master. There’s some fantastic performance improvements across the board, but the one I would like to highlight is the one for string.

This means a route that just returns a simple string. Technically this is not a view, but we used it as a reference point because it’s the simplest form of response. A 28% increase in performance is pure optimization in the request/response life cycle and even then it all came down to some small, clever, changes.

What? You mean the green bar? Oh! That green bar. Well, turn’s out that hitting csc.exe on each request can really kill performance really horrible.

All in all, we are very happy with the changes we made here.

Razor

As if the massive performance boost wasn’t enough we managed to squeeze in some very anticipated features. The two big ones are support for partial views and layouts. We managed to decipher the crypto that is layout support in the razor parser (poor Steve used reflector more than anyone should have to do in a single stretch) so the implementation we provide should be wired up like it is in ASP.NET MVC. There are also some other changes that we have documented on our wiki.

Super-simple view engine

The big changes here are added support for partial views and layouts. This little engine is starting to become quite rich on features but it is still extremely small and embedded into the Nancy dll, so it is accessible when ever you are working on a Nancy application.

Dotliquid

We added a new view engine, this time for the dotliquid markup syntax.

And Bob’s your uncle!

That’s it! It’s not all of it, but that’s the essence of it. We did fix bugs, improve code quality, create more NuGet packages and a lot of small changes as well. So, if you haven’t already, go check it out at nancyfx.org or at the official NuGet feed.

Until next time, happy coding!

Detecting anonymous types on Mono

Little more than a week ago, I sat down to add the possibility of using anonymous types as models for views in Nancy. Now, since not all view engines can handle anonymous types as their model I decided I would intercept them, along the way to the view engine, and convert them into an ExpandObject instead.

In order to do this I needed to detect them first, and after poking around the reflection API, and use Google + Twitter to confirm it, I came to the conclusion that there is nothing in there that will tell me if the instance I have is of an anonymous type or not.

Then I got a tweet from Joseph Gray, also known at @MrJosephGray on Twitter, sent me a link to a blog post by Jef Claes titled Checking for anonymous types and it contained just what I needed. It works beautifully, until I ran my code on Mono that is.

Even though the blog post is not clear on it, I was aware of that the detection method relies on undocumented naming conventions and no guarantee that any of the traits, that it checks, won’t be changed in the future by Microsoft. That is also why I was not surprised that there were issues while running it on Mono.

After taking the debugger out for a quick spin it was evident that it was the type name that was the culprit. On Mono (at least on 2.10 that I am running), the name of the generated type contains AnonType and not AnonymousType and it was a trivial task to patch the extension method to check for that as well.

The full implementation that I am using in Nancy is listed below

Nancy on Hanselminutes and the awesome community behind it

A week ago I was invited to participate in he Hanselminutes postcast by Scott Hanselman to talk about Nancy and Micro Web Framework. The recording for episode #270 can be found at Nancy, Sinatra and the Explosion of .NET Micro Web Frameworks with Andreas Håkansson

I had a great time talking to Scott, who is an excellent host, but one thing I did not get an opportunity to do was to extend my gratitude to the awesome people that are forming up a community around the project, everybody from the people that blog, tweet, screencast or in some other way help Nancy grow into an awesome framework – so thank you to all of you!

The following people have all contributed to the Nancy repository and have helped us get many of the awesome features and bug fixes (if your name should be on this list, but it not, please drop me a line and I will get sorted out!)

Andy Pike, Bjarte Djuvik Næss, Chris Nicola, David Hong, Graeme Foster, Guido Tapia, Hernan Garcia, Ian Davis, Jonas Cannehag, José F. Romaniello, Karl Seguin, Luke Smith, James Eggers, Jason Mead, Jeremy Skinner, João Bragança, Johan Danforth, John Downey, Maciej Kowalewski, Martijn Laarman, Mindaugas Mozûras, Patrik Hägne, Pedro Felix, Piotr Wlodek, Phil Haack, Robert Greyling, Simon Skov Boisen, Steven Robbins, Thomas Pedersen, Troels Thomsen, Vidar L. Sømme

I would like to extend a special thank you and shout out to my friend and co-conspirator Steven Robbins a.k.a @GrumpyDev on Twitter. He is a continuous source of awesome for Nancy and the project is better for having him onboard, that is one thing I am certain on. Thank you buddy!