Friday, September 26, 2014

A First Look at Using C# 6 - Auto Properties

This is the second post about the C# 6 features I used when moving Nancy.Linker over to C# 6. The first part was about primary constructors. This one in about new auto-property features.


Auto-Property Initializers and Getter-Only Auto-Properties

Just like fields can be initialized from primary constructor arguments in C# 6 so can auto properties. In Nancy.Linker this is used in the Registration class where cuts out a good deal of ceremony.

Furthermore auto properties do not need to a setter anymore. This is very different from autoproperties with a private setter, because an auto-property without a setter is immutable, where as an auto-property with a private setter only protected against code outside of the class mutating it.

The Registration class in Nancy.Linker implements the IRegistrations interace from Nancy, which looks like this:



Notice that this is 3 getter-only properties. Until now you would have implement these either with explicit getters, or as auto-properties with setters. In C# 6 their implementation can follow the interface more closely and as an added bonus the whole class becomes immutable. The code for the Registration class becomes:



I like these 2 features because:
  1. They make creating immutable types in C# a lot easier, which I think we will see a whole lot more of in C# code in the near future.
  2. The cut down on the amount of ceremony needed to implement interfaces like IRegistrations

Sunday, September 21, 2014

A First Look at Using C# 6 - Primary Constructors

The other night I moved Nancy.Linker to C# 6 - this is the first part of a summary of what I changed along with quick introductions to the C# 6 features I used. Nancy.Linker is a small library (1 interfaces, 2 production classes, 2 test class), so not everything comes into play there - but the 3 C# 6 features I'm most eager to get, namely primary constructors, auto-property initializers and getter-only auto-properties, all did. For the full overview of C# 6 features visit the language features status page on the Roslyn codeplex site.

Before diving in I will note that this is based on code written using the 'experimental' flag for the compiler that comes with Visual Studio 14 CTP 3. Since this is a pre-release of the compiler things may change, but judging from the language features status page linked above the features described here are fairly stable.


Primary constructors

The first feature I used was primary constructors. In Nancy.Linker only 1 of the production classes and 1 of the test classes have non-default constructors, and they only have 1 constructor each. Classes with 1 explicit constructor are prime candidates for primary constructors, so i gave both a primary constructor.

Primary constructors add new C# syntax for declaring a constructor. While multiple constructors are still allowed only one of them can be the primary one. From the outside a primary constructor is no different than any other constructor; its primary-ness is only visible inside the class. The declaration of a primary constructor is part of the class declaration where an argument list is added:



which is equivalent the old ResourceLinker constructor:



Once a primary constructor is declared the variables in the argument list are available for initializing fields and properties in the class. In the ResourceLinker class the old constructor assigned the two constructor arguments directly to private fields. With primary constructor syntax this becomes:



I like this for two reasons.
  1. By pulling the constructor argument list all the way up to the line declaring the class primary constructors place more emphasis on this list. I find that the constructor argument list is quite important, because it shows what is needed to create an instance of the class. Particularly so if you use DI and prefer constructor injection.
  2. It saves a few lines of trivial initializtion code.

Primary Constructor Bodies

My previous experience with primary constructors is from Scala in which everything between the open curly brace at the start of the class and the closing one at the end is the body of the primary constructor. You can put arbitrary code into the class definition and it will run when instances are created. In my experience this is done fairly often in Scala code, and it is a feature I've been happy with in Scala. In C# 6 adding is a body to a primary constructor is - in my opinion - somewhat less elegant because it requires you to add a scope somewhere in the class where all the primary constructor body code is placed.

The tests for Nancy.Linker uses a small NancyModule called test module, which sets up a few routes, that the tests then use. Before that class looked like this:



Take line 8 as an example. This is not simlpy an assignment to a field or a property. Therefore it has to be part of the primary constructor body, so moving this class over to having a primary constructor means turning it into:



See that pair of curly braces around the constructor body? That is that extra scope delimiting the body of the primary constructor.

I still like the changes to this class for the same reasons as stated above, but I don't like the necessity of putting all the primary constructor body code into a scope because:
  1. It is less flexible than the Scala counterpart, because all the code has to be together.
  2. Aestetics: The code is at an extra level of indentation and has to be surrounded by a pair of somewhat dangling braces.


Saturday, August 30, 2014

Using Nancy.Linker with Razor Views

First things first: I recommend that you use Nancy.Linker to generate link in the route handler not the view code, as described in my last post. If you insist on generating the links in the view code here is how to make Nancy.Linker work with Razor views.

Firstly you need to pass an instance on IResourceLinker and the NancyContext to your view. This works just like passing any other object from the handler to the view  - in your Nancy module you have your route handler pass the IResoureLinker and NancyContext objects as part of the model to the view you want to render:




The NancyContext must  passed along with the IResourceLinker, since Nancy.Linker needs it to generate links. Once you've done this you are almost ready to use Nancy.Linker in your Razor code, but first you need a little bit of web.config gymnasitcs. This is because IResouceLinkker returns System.Uri objects, which Razor does not know about unless you tell it where to look. To tell Razor, add this to your web.config:



Refer to the Nancy documentation for a proper explanation of this.
Having added the web.config snippet you can go ahead and use Nancy.Linker to generate links in the Razor code:



That's all folks!