DDDNorth – a day of free learning in Bradford

It was a 5am alarm that woke myself, and likely my colleagues, on a saturday morning when most people would be comfortably in the land of nod, or contemplating how best to laze away their saturday. For these tombola developers though, it was a drive down to Bradford to attend DDDNorth – a day long free conference setup and run by the community and supported by some brilliant sponsors. The drive down was uneventful, and we were presented with caffeine and brekky before the talks commenced.

Myself, Michael Tomaras, and Luke Hill were in attendance – I’ll relay the talks that were most inspiring to me.

There were two key talks for me – one, which I’ve heard and read a bit about anyway, was around the Spotify model for scaling agile by Stephen Haunts, and the second was a war story from Nathan Gloyn after 18 months of working on a number of projects where microservices played a part.

Microservices – Nathan Gloyn

We’re on a journey of growth at tombola that is seeing us diversify our software products in order to facilitate growth more readily – and although I’ve studied significantly around architecting, building, and supporting microservices, I thought a talk dedicated to ‘what I’ve learned after a year of building a system’ would be right up my street.

There was a bit of background about microservice patterns (and anti-patterns), and discussions around indetification of bounded contexts, fat vs thin microservices and just some key gotchas – security, service discovery, logging (and logging, and logging, and logging some more).

Some key takeaways:

  • Deployment (deploy small, avoid single repo for multiple services),
  • Identity and Authorisation (get these right up front – don’t attempt to retro fit it, it’ll get inordinately harder),
  • Build based upon need (not because it’s cool),
  • Configuration (strongly consider configuration management – consul/zookeeper/et al),
  • Logging (you can never log too much),
  • Monitoring (ensure you understand the baseline and health of each component, but ensure you are monitoring the system as a whole too),
  • System flow (correlation / session tokens in order to track journeys and requests through various systems is crucial)

None of these new, though distilled well by Nathan and he delivered an effective talk. The only thing missing from this for me was around the organisational change required to support microservices – a move we’re currently undertaking in terms of a shift away from a more monolithic single deploy application into many more smaller, co-ordinated, API driven services. Conways Law and team structure vs architecture design within an organisation is of key interest to me, and I think it’d have been nice to see a little more around this in the talk.

Scaling Agile with the Spotify Model – Stephen Haunts

Another useful war story about how Stephen and the team at his previous employer had managed the growth of the organisation via the spotify model which they modified in a rather comic ‘lord of the flies’ motif, with islands (multiple companies) and lookouts (marketing/sales type roles that protected the developers from the external landscape that was very much waterfall / deadline driven).

Some really refreshing pointers during this for me on just how best to empower and inspire the workforce while adapting to the growth and change of the organisation.

Key slide of the day for me though was one presented from a Harvard Business Review article.

This is such an incredible visual metaphor for just how satisfied, engaged, and inspired employees would be within an organisation, and I think this will be the one image that goes up on the wall in the office – definitely something to aspire to.

Crosspost

Post is also available at ops.tombola.co.uk (or will be, soon!)

Roundup

A brilliant day of learning, some really useful talks, and a day to get some discussion with peers from the industry – all for the bargain price of £0.00. Further discussions with peers in other sectors who highlighted that recruitment for them was as difficult as it was for us, no matter how cool or interesting the work is you are doing (by the way, we’re hiring! see our careers site)

Free learning, free food, free chat, free inspiration – what’s not to like? Thanks DDDNorth.

DDD Scotland 2016 – A sunny day in Edinburgh

Saturday saw an early start to travel from the north east up to Edinburgh for the first DDD Scotland in a number of years and the hashtag was already seeing activity, so it was clearly going to be a good day.

First, and only, disappointment of the day – no coffee at the venue for breakfast!  They made up for it later in the day, though a cup of rocket fuel would have helped after starting at 5am.

tl;dr

Some very good talks, and some real takeaways from the day – as with any event of this type, a re-firing of the engines is definitely part of the aim – new ideas, new directions, new approaches – and the day most certainly delivered on this.

I was particularly impressed with the guys from Skyscanner – both culturally and technically they have identified their problems well, and effectively delivered solutions and organisational change in order to minimise pain – a success story in the making.

A Squad Leaders Tale – the Skyscanner squads model

Keith Kirkhope (@kkirkhope)

The squads model from spotify has been widely discussed and is a model that Skyscanner has adopted (and adapted) that model during a period of organisational and architectural change, and it would appear that they have done so to good effect.

They had the typical growing pains of any organisation that has gone from early success and grown significantly really:

  • They’d hit product gridlock
  • Their source control/release process was unwieldy
  • They were broken into functional teams (front end, etc. etc.

They were able to apply a lot of thinking around the theory of constraints, and indeed highlighted that they realised they were only as fast as their slowest unit. 

They adopted the squads model, though included a few modifications to better fit their organisational structure (they included squad leads at the top of each squad, but also brought in a tribe lead, a tribe engineering lead, and a tribe product lead to give better oversight across each squad).

Each squad is essentially self managing and self directing – they come up with their own goals, metrics, and success criteria (and example given was ‘to help users find their ideal flight(s) and book it as easily as possible’)

Some really positive side effects from this empowerment – for example, project leads become redundant, the product owner becomes one of the key foci.

I managed to ask a number of questions in this talk to better grasp the model, though unfortunately the one I didn’t ask was around Conways Law.  This organisational change seemed to be fundamental to their move from monolith to micro services, and I suspect without it they could not have so effectively broken down that monolith.  This change was a top down led change, and it’d be fascinating to learn more about the drivers behind it.  It’s the first time I’ve seen the direct impact of the communication structures of an organisation directly impacting the design of the systems.

Breaking the monolith

Raymond Davies (@radyrad88)

Another talk from Skyscanner, this one a very detailed history of skyscanner’s journey from inception through to current day and covering a great deal of the technical decisions made along the way – some of which I shall investigate as part of our own journey at tombola as we face some similar issues/growing pains.

They moved from classic asp, through webforms/mvc, to mvc, and eventually arrived at their current architecture which is evolving towards a micro service model.

Some key takeaways from this one:

  • Aggressively decommission older/legacy ‘kill it with fire’
  • Theory of constraints played a bit part in their evolution
  • They weren’t affraid to look at alternative team structures and architectures

Some technologies to look at:

  • varnish and esi, riverbed traffic manager

This and the squads talk were the high point of the day for me.

Other talks

Windows brings docker goodness – what does it mean for .net developers (Naeem Sarfraz)

A great talk and the speaker was very knowledgeable – the current state of the nation for docker looks good.  Certainly not yet at the point where you’d want to deploy (far from it), but the technology is maturing nicely.

Versions are evil – how to do without in your APIs (Sebastian Lambla)

The holy wars on RESTful endpoints, and his points were very well argued.  Worth seeing the video below.

Slides From Talks

ASP.NET Core 1.0 Deep Dive – Christos Matskas

You Keep Using the word agile… – Nathan Gloyn

Versions are evil – how to do without in your API – Sebastian Lambla

“Advanced” Functional Programming for Absolute Beginners – Richard Dalton

CQRS and how it can make your architecture better – Max Vasilyev

Ladies and Gentlemen the plane is no longer the problem – Chris McDermott

Breaking the Monolith (video) – Raymond Davies

BuildStuff Lithuania 2015

Just returned from a fantastic trip to Lithuania to attend BuildStuff 2015 and thought I’d get my notes down into a blog post to help distill and to build a brown bag session for the team at work.

The focus this year seems to have been heavily around a few key topics:

  • Functional programming played a big part and it was clear from even those talks that weren’t functional that there is a shift across to this paradigm in a lot of people’s work.
  • Agile process and approaches featured heavily as an underpinning, and indeed one of the best talks of the conference for me was Liz Keogh’s talk on ‘Why building the right thing means building the thing right’
  • Micro services (micro services, micro services, micro services) is still the hipster buzzword, though at least there were hints that the golden gooses’ egg has cracks in it (they’re still seen as a very positive thing, though they’re not without their own costs and limitations)
  • APIs naturally featured heavily in a few talks as people move more towards service orientation/micro services, and there are now a healthy set of talks on the ‘how do do this part right’
  • Continuous Integration/Continuous Delivery seems to have become less popular/less cool as a topic, but I was able to get some very useful insights on the conference that helped a lot.

You can see the full list of talks I attended here.

My tweet stream for the conference is here, and the full tweet stream for the #BuildStuffLT hashtag is here.

I attended some talks based upon the calibre of the speaker, and in some cases that was a disappointment – I of course won’t mention names, though there were a few of the bigger personalities that disappointed in presentation.

Couple of the talks I took more notes at (in chronology order);

5 Anti-Patterns in Designing APIs – Ali Kheyrollahi (@aliostad)

I loved the visual metaphor presented early in this talk of the public API as an iceberg where the vast majority of the activity is under the surface in either private APIs or business logic, and the public facing element is a small part of it.

The anti-patterns were listed as follows:

  • The transparent server – Exposing far too much information about the internals or the implementation. Having to request resources with your userId in the URL (get-details/12345 instead of /get-details/me) for example.
  • The chauvinist server – Designing the API from the servers perspectives and needs and pushing that thinking and process to any clients if they wish to consume it. Interestingly, Ali came off the fence and suggested HATEOS as an anti-pattern in this regard – I’m not convinced, but it was refreshing to see a strong opinion on this.
  • The demanding client – where certain limitations are enforced from a client perspective (e.g. forcing versioning into the URL as opposed to the headers)
  • The assuming server – where the server assumes knowledge on issues that are inherently client concerns. Good example here was pagination – /get-winners/page=1 versus /get-winners?take=20&skip=0 – we don’t know anything about the form factor on the server, so a ‘page’ has no context.
  • The presumptuous client – a client taking on responsibilities that it cannot fulfil (e.g. client implementing an algorithm that the server should handle, client acting as an authority for caching/authorisation etc.)

Another analogy I liked was in thinking of the API like a restaurant. The front of house is pristine, controlled, serene, structured. How the food arrives at the table is unimportant, and the kitchen (the server side of the API) could be a bed of chaos and activity, so long as the delivery to the front of house is pristine.

Service Discovery and Clustering for .net developers – Ian Cooper (@icooper)

This was listed as .net developers, though in reality the concepts equally applied across other technology stacks but it was nice to see code examples in .net for some of these.

He covered some of the fallacies of distributed computing:

  • The network is reliable
  • Latency is zero
  • Bandwidth is infinite
  • The network is secure
  • Topology doesn’t change
  • There is one administrator
  • Transport cost is zero
  • The network is homogenous

And also covered a number of things around Fault Recovery:

  • Assume a timeout will happen at some point
  • Retry pattern (http status code 429 – ‘Retry-after’)
  • Circuit breaker pattern (another mention for Polly here, which is an awesome library)
  • Introduce redundancy (be careful where state is stored)

Discovery was discussed at length (naturally), and he covered both Server and Client side discovery, as well as the general tooling available to help manage this (Consul, Zookeeper, AirBnB SmartStack, Netflix Eureka, etcd, SKyDNS) and covered the importance of self registration/de-registration of services.

A lot of practical/good content in here and a cracking speaker. Really liked the way he delivered demos via screencast so that he could talk rather than type – I think a lot of speakers could benefit from this approach.

Why Building the Right Thing means Building the Thing Right – Liz Keogh (@lunivore)

A lot of this talk focussed around Cynefin, a framework that seems to have arrived from Dave Snowden and describes a system for understanding and evaluating complex systems as they evolve. This talk covered a number of known concepts to me, but in a new way, so it very much hit upon my ‘must learn more about this’. It covered massively more than I could do justice to (though the link to the talk above from Liz is very similar to the one she presented), and she covered a whole pathway through an organisations agile fluency.

One of two talks at the conference that really gave me ‘take aways’ to go and learn and get better at – so massively happy I attended.

ASP.NET 5 on Docker – Mark Rendle (@markrendle)

This is the first time I’ve seen Mark present and I hope it shan’t be the last. Brilliantly clever bloke, fantastic presentation style, and clearly knows his topic areas well (he gave a closing keynote too which was equally good).

I played with vNext of asp.net in early beta, so it was incredible to see how far it’s come since then. He had brought it all the way up to date (RC1 of the framework had been launched the day before, and he included it in the talk), and the flow and interaction has become really polished.

I have to admit to being behind the curve with regards Docker – understand it conceptually, have kicked up a few docker images, but nothing anywhere near production or usable at any scale. I don’t really have any solid need for it right now, though the talk did demo how easy it was to fire up and deploy the code to a docker container and it’s possibly something to look at once the container/unikernal platform settles down.

All of the demo’s were given on linux/mono, though that evening (tragic I know) I re-worked through the talk on OSX and it all worked a treat so it does indeed seem like Microsoft has the open source/multi-platform delivery message correct here. I’ll do a follow up post on this as it’s now the topic that will take up most of my play time in the evenings.

Continuous Delivery – The Missing Parts – Paul Stack (@stack72)

I talk with Paul at most conferences and have been to his talks in the past, so I hadn’t really thought I’d attend this talk (I’ve heard all he has to say!) – so glad I did. It started after a twitter conversation pre-talk with him and Ryan Tomlinson around where the complexity in micro-services exists (away from the code, and more towards the wiring/infrastructure of it all). Thankfully, Paul’s talk focussed around exactly those topics and it was almost a rant towards the micro-services fandom that is exhibited heavily at conferences currently.

He covered the key tenets of Continuous Delivery:

  • Build only once (never ever build that ‘same’ binary again once you’ve shipped it)
  • Use precisely the same mechanism to deploy to every environment – that doesn’t mean you can use right click, publish to push up to production 😉
  • Smoke test your deployment – this is key – how do you know it works?
  • If anything fails, stop the line! It’s imperative at any stage that you can interject on a deploy that fails

Covered some common misconceptions about continuous delivery:

  • It’s something only startups can do – it’s true that starting in greenfield makes it easier to build upon, but anyone can move towards continuous delivery
  • It’s something that only works for nodeJS, Ruby, Go developers – any ecosystem can be pushed through a continuous delivery pipeline
  • We can hire a consultant to help us implement it – domain knowledge is crucial here, and someone without it cannot come in and help you solve the pain points
  • Continuous delivery is as simple as hooking up github to your TC account – all parts of the pipeline really need to be orchestrated and analysed

There was a really good example of successful continuous delivery and it was a quote from facebook. They deploy new functionality to 17% of the female population of new zealand. Basically, by the time the major metropolitan cities come online, they already know if that feature is working or not.

Some other key takeaways from this talk – you have to ensure you deliver upon the 4 building blocks of DevOps (Culture, Automation, Measurement, and Sharing) in order to ensure you have a strong underpinning. Again, this harks to the micro-services talks – just moving your auth system into a separate service doesn’t give you a micro-service. You need solid infrastructure underpinning it, you need orchestration, you need instrumentation and logging, you need some way of that service being discovered, etc. etc.

Continuous Delivery (to me) feels like a solid building block that needs to be in place and working well in order to act as a feeder for things that micro-services would hinge upon.

He mentioned the Continuous Delivery Maturity Model, and it’s worth everyone reviewing that to see where they sit in each category. One of the key things for my organisation is to review our cycle time and see just what our flow looks like, and if there are any key areas that we can improve upon.

CraftConf 2015 – did someone say microservices?

I’ve just returned (well, I’m sitting on a balcony overlooking the Danube enjoying the sunshine) from two days at CraftConf 2015 and thought I’d share my thoughts on my first attendance to this conference (it’s in it’s second year).  Firstly, lets get the cost aspect out of the way – this conference is incredibly good value for money.  Flights, conference ticket and hotel came to less than the cost of most 2 day conference tickets in London, yet the speaker line up is incredible and the content not diminished because of this economy – if you have difficulty getting business sign off on conferences in the UK, you could do worse than look at this.  That said, a conference is all about the content so lets talk about the talks.

Themes – Microservices, microservices, microservices

Thankfully, more than one person did say that microservices for them was ‘SOA done properly’ – the talks I gravitated toward tended to be around scaling, performance, cloud, automation and telemetry, and each of these naturally seemed to incorporate elements of microservice discussion.  Difficult to escape, though I guess based on the number of people who haven’t yet adopted a ‘small, single purpose services within defined bounding contexts’ (ourselves included) in the room, it was a topic ripe for the picking.

Talks

I won’t cover all of the talks as there was a lot of ground covered over the two days – thankfully they were all recorded so will be available to stream from the ustream site (go give the craft conf link above) once they’re all put together.

That said, there were some that stood out for me:

Building Reliable Distributed Data Systems

Jeremy Edberg (Netflix, @jedberg)

I’m a long time fan of netflix’s technology blog, so seeing them give a talk was awesome. I think this one sat up there as one of the best of the conference for me. A number of key points from the talk:

  • Risk in distributed systems – often on releasing teams look at risk to their own systems, risks in terms of time of day, but often overlooked is the risk to the overall ecosystem – our dependencies are often not insignificant and awareness of these is key in effective releasing
  • A lot of patterns were discussed – bulkheading, backpressure, circuit breakers, and caching strategies that I really must read more around.
  • Queuing – the approach of queuing anything you’re writing to a datastore was discussed – you can monitor queue length and gain far better insight into your systems activity.
  • Automate ‘all the things’ – from configuration and application startup, code deployment and system deployent – making it easy and quick to get a repeatable system up and running quickly is key.
  • ‘Build for 3’ – when building and thinking about scale, always build with 3 in mind – a lot of the problems that come from having 3 systems co-ordinate and interact well continue on and are applicable once you scale up.  Building for 2 doesn’t pose the same problems and so bypasses a number of the difficult points you’ll cover when trying to co-ordinate between 3 (or more).
  • Monitoring – an interesting sound byte, though alert on failure, not the absence of success.  I think in our current systems at work we’re mostly good at this and follow the pattern, though we can, as always, do better.

Everything will break!

Deserving of it’s own section as this really has to be handed to netflix as an incredible way of validating their systems in live.  They have a suite of tools called the simian army which are purposely designed to introduce problems into their live systems.  The mantra is ‘You don’t know your ready unless you break it yourself, intentionally and repeatedly’ – they have a number of different monkeys within this suite, and some of them are run more regularly than others, but this is an astonishing way of ensuring that all of your services in a distributed architecture are designed around not being a single point of failure, or not handling things like transient faulting well. 

It is seen as an acceptable operational risk (and indeed he confirmed they had) to take out customer affecting live services if the end goal is to improve those services and add more resilience and tolerance to them.  Amazing!

Incident Reviews

Their approach to these fitted well with what I’d hope to achieve so thought I’d cover them:

It was all about asking the key questions (of humans):

  • What went wrong?
  • How could we have detected it sooner?
  • How could we have prevented it?
  • How can we prevent this class of problem in the future?
  • How can we improve our behaviour?

Really does fit in with the ‘blameless postmortem’ well.

The New Software Development Game: Containers, microservices, and contract tests

Mary Poppendieck (poppendieck llc, @mpoppendieck)

A lot of interesting discussion in this keynote on day two, but some key points were around the interactions between dev and ops and the differing personality types between them.  The personality types were broadly broken down into two: Safety focussed and promotion focussed.  The best approach is the harness both personalities within a team, and ensure that they interact.

Safety focussed

These people are about failure prevention – asking ‘is it safe?’ and if not, what is the safest way that we can deliver this?  Motivated by duty and obligation.  They find that setbacks cause them to redouble their efforts whereas praise causes a ‘leave it all alone’ approach.

Promotion focussed

‘All the things!’ – all about creating gains in the ‘lets do it’ mindset. They will likely explore more options (including those new and untested).  Setbacks cause them to become disheartened whereas praise focuses them and drives them.

As a ‘promotion focussed’ person primarily, I’ve oft looked over the fence at the safety focussed and lamented – though really I think understanding that our goals are the same but our approaches different is something I could learn from here.

From monolith to microservices – lessons from google and ebay

Randy Shoup (consulting cto, @randyshoup)

Some interesting content in this one – his discussion around the various large providers and their approaches:

Ebay

  • 5th complete rewrite
  • monolith perl -> monolith c++ -> java –> microservices

Twitter

  • 3rd generation today
  • monolithic rails -> js / rails / scala –> microservices

Amazon

  • Nth generation today
  • monolithic c++ -> java / scala –> microservices

All of these have moved from the monolithic application over to smaller, bounded context services that are independently deployable and managed.

He was one of the first (though not the last) to clarify that the ‘microservices’ buzzword was, for him, ‘SOA done properly’.  I get that microservices has it’s own set of connotations and implications, though I think it’s heartening to hear this as it’s a view I’ve held for a while now and it seems others see it the same way.

Some anti-patterns were covered as well.

  • The ‘mega service’
    • overall area of responsibility is difficult to reason about change
    • leads to more upstream/downstream dependencies
  • Shared persistence
    • breaks encapsulation, encourages backdoor interface violations
    • unhealthy and near invisible coupling of services
    • this was the initial eBay SOA effort (bad)
  • “Leaky abstraction” service
    • Interface reflects providers model of the interaction, not the consumers model
    • consumers model is more aligned with the domain.  Simpler, more abstract
    • leaking providers model in the interface constrains evolution of the implementation

Consensus is everything

Camille Fournier (Rent the runway, @skamille)

Not a lot to say about this one as we’re still in the process of looking at our service breakout and on the first steps of that journey, though I’ve spoken to people in the past around consensus systems and it’s clearly an area I need to look into.

Some key comparisons between zookeeper and etcd, though as Camille highlighted, she hadn’t had enough time with Consul to really do an effective comparison with that too.  Certainly something for our radar.

Key takeaway (and I guess a natural one based on consensus algorithms and quorum) was odd numbers rule – go from 3 to 5, not to 4 or you risk locking in your consensus.

Summary

A great and very valuable conference – discussion with peers added a whole host of value to the proceedings and to see someone using terraform tear down and bring up a whole region of machines (albeit small) in seconds was astounding and certainly something I’ll take away with me as we start our journey at work into the cloud.

A lot of the content for me was a repetition of things I was already looking at or already aware of, though it certainly helped solidify in me that our approach and goals were the correct ones.  I shall definitely be recommending that one of my colleagues attend next year.

Switching the client side build library in visual studio 2013 MVC template to gulp and bower

Why?

A lot of people use Mads Kristensen’s absolutely awesome Web Essentials plugin for Visual Studio – we use it for less compilation, and bundling of our less/js.  It does however fall down when you need to use it in a continuous integration context, so we find that we keep the compiled/bundled output in our repository.

Couple that with the fact that in the next release of visual studio, gulp/grunt/bower are becoming first class citizens in terms of it’s support out of the box.

Scott Hanselman’s point in that post is a valid one – nuget is a superb addition to the .net ecosystem, and compare it to the dark days of ‘download a DLL from somewhere and hope’, it’s revolutionised .net development.  But there are other, arguably far better, and certainly far richer ecosystems out there for client side build, which on the one hand is absolutely awesome (npm is easy to build for and publish modules to), and on the other hand, daunting (I counted at least 15 modules that would simply minify my css for me).  Thankfully, the community talks/blogs a lot about this, so finding commonly used packages is as easy as reading from a number of sources and seeing which one comes out on top.

Microsoft are to be applauded for taking this approach and opening up the pipeline in this way – their whole approach recently with OSS of the .net clr, as well as the potential promise of a reliable .net on linux via vNext, and it’s a great time to be a .net dev.

All code for this example post is available at https://github.com/terrybrown/node-npm-gulp-bower-visual-studio

What is Gulp?

I won’t go into detail, as many other posts cover it well.  Essentially, it is a streaming build system written in node that allows people to create tasks and build up a pipeline of activities such as transforming less, copying files, validating javascript, testing, etc.  It is a more recent addition to the market (grunt, a tool with similar aims, though a different approach is another in the same arena).

What is Bower?

Essentially, a package manager for front end libraries (be they javascript, css, etc.) – think of it at a rudimentary level like nuget for client libraries.  There is a very good short video on egghead.io

Holy wars solved early – Gulp vs Grunt

Clever people have written about this.  I personally prefer the streams approach and the code over configuration driven nature of gulp over the ‘temp file all the things’ and config based approach of grunt.

Getting Setup – local dev machine + visual studio

Machine needs to be running node and gulp (gulp needs to be installed globally)

Node has just hit v 0.12 which has a number of updates (not least to streams3 and away from the somewhat interesting streams2)

node --version

Will confirm which version of node you’re running.  You don’t need the latest version, though the update in 0.12 has been a long time coming.

Setting up gulp/bower

npm install gulp -g
gulp --version
npm install bower -g
bower --version

TRX – Task Runner Explorer: This will give you a custom task runner for gulp within visual studio.

NPM/NBower Package Intellisense: Who doesn’t like intellisense right?

Grunt Launcher: Not ideally named, but a great little add on to give you right click support for gulp/bower and grunt.

You may also want to follow the steps in http://madskristensen.net/post/grunt-and-gulp-intellisense-in-visual-studio-2013 to get full intellisense.

Note: Switch off build in web essentials (it’s being used purely for intellisense)

File > New Project – and a tidy up

We want to hand over all JS and CSS handling to gulp.  This includes bundling and minification, as well as hinting/linting. We’ll start with the default MVC template from Visual Studio as the basis of our work.

Remove asp.net bundling/optimization

In the current template for MVC sites, Microsoft provide a handy bundling mechanism that although fine for smaller sites, still maintains the same problems as above and doesn’t give you separate control over your ‘distribution’ JS/CSS.  We’ll remove:

Microsoft.AspNet.Web.Optimization (and dependencies WebGrease, Antlr, Newtonsoft.Json)

This will also involve a few changes to web.config and the codebase (see https://github.com/terrybrown/node-npm-gulp-bower-visual-studio/commit/5cfb58b8e57faa4c518a067fa473d740e43725a3)

Remove client side libraries (we’ll replace these later)

  • bootstrap 3 (bower: bootstrap)
  • jquery (bower: jquery)
  • jquery validation (bower: jquery-validation)
  • jquery unobtrusive validation (bower: jquery-validation-unobtrusive)
  • modernizr (bower: modernizr)
  • RespondJS (bower: responsd)

Setting up Bower

bower init

This will lead you through a number of questions (accept defaults throughout for now, though you can read up on the options here)

You will end up with a bower.json file that will look something like:

image

Re-installing javscript and css dependencies

Take all of the package references above that we removed (the bower versions) and run the following on the command line:

bower install bootstrap jquery jquery-validation jquery-validation-unobtrusive modernizr respond --save

Do NOT forget the ‘- -save’ postfix at the end – this will ensure that your bower.json is updated with the local dependencies.

This will start the download and install, and you will end up with a new folder in your solution called ‘bower_components’ folder which contains all of the local dependencies.  Ensure you add this folder to your .gitignore (or source control ignore file of choice).

As a temporary step, switch to visual studio – add the ‘bower_components’ folder to your solution, and re-map all of your js/css files from the default template to the newly downloaded versions.

image

Setting up the build with Gulp

Firstly, we need to get this local solution ready to receive npm packages as dependencies (gulp + the other supplemental libraries we’ll be using are available via npm.

npm init

Again, accept all of the defaults really, or whatever you fancy in each field.

The examples from here down will be somewhat contrived – your own use case can dictate what you do at each step here, but for the purposes of example, what we want to achieve is:

  • Deliver all jquery and jquery validation libraries into a single request
  • Deliver bootstrap and respond as a single request
  • Create a basic more modularised structure for our CSS using less and then concatting/minifying as part of the build

In our real use cases at work, our needs are far more complex, but the above will serve as an example for this post.

Setting up a default ‘gulpfile.js’.

var gulp = require('gulp');

// define tasks here
gulp.task('default', function(){
  // run tasks here
  // set up watch handlers here
});

You can name and chain tasks in gulp really easily – each one can act independently or as part of an overall build process, and TIMTOWTDI (always) – what I’ll put forward here is the version that felt easiest to read/maintain/understand.

Deliver multiple vendor libraries into a single request

var gulp = require('gulp');
var del = require('del');
var concat = require('gulp-concat');

var outputLocation = 'dist';


gulp.task('clean', function () {
	del.sync([outputLocation + '/**']);
});

gulp.task('vendor-scripts', function () {
	var vendorSources = {
		jquery: ['bower_components/jquery/dist/jquery.min.js',
	'bower_components/jquery-validation/dist/jquery.validate.min.js',
	'bower_components/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js']
	}

	gulp.src(vendorSources.jquery)
		.pipe(concat('jquery.bundle.min.js'))
		.pipe(gulp.dest(outputLocation + '/scripts/'));
});


gulp.task('default', ['clean', 'vendor-scripts'], function(){});

Ok, there are a number of things in here – key points:

  1. Read from the bottom up over – if you issue a straight ‘gulp’ command on the command line, you wil always run the ‘default’ task.  In this case, it doesn’t do anything itself (the empty function as the third param), but instead has a chained dependency – it’ll run ‘clean’ first, then (upon completion) run ‘vendor-scripts’ tasks.
  2. ‘clean’ task uses the ‘del’ npm module to clean out the output folder we will be pushing the built scripts/css to.
  3. ‘vendor-scripts’ uses the ‘gulp-concat’ npm module to simply join an array of files together (in this case, the jquery + jquery validation files)

if you switch to a command prompt window and run ‘gulp’ on it’s own, you will see output similar to:

image

And in visual studio, you will now see a hidden ‘dist’ folder there with the output of what you have just generated (remember to update your .gitignore – you do not want to commit these)

Disabling Web Essentials

Less has been our tool of choice for our CSS for some time now, and web essentials really did/does rock as a VS plugin to aid your workflow on those (nice inbuilt bundling, compilation, etc.  That said, now that we’re moving to a more customised build process, we need to switch the compilation side of it off.

Tools > Options > Web Essentials

Switch everything in ‘Javascript’ and ‘LESS” to false.

Deliver minified and concatenated CSS from LESS

We contrived a number of .less files in order to create the proof of concept:

_mixins.less

@brand_light_grey_color: #EFEFEF;

.border-radius(@radius: 4px) {
	-moz-border-radius: @radius;
	-webkit-border-radius: @radius;
	border-radius: @radius;
}

layout.less

@import "_mixins.less";

body {
    padding-top: 50px;
    padding-bottom: 20px;
}

/* Set padding to keep content from hitting the edges */
.body-content {
    padding-left: 15px;
    padding-right: 15px;
}


/* Override the default bootstrap behavior where horizontal description lists 
   will truncate terms that are too long to fit in the left column 
*/
.dl-horizontal dt {
    white-space: normal;
}

div.rounded {
	.border-radius(4px);
}

forms.less

@import "_mixins.less";

/* Set width on the form input elements since they're 100% wide by default */
input,
select,
textarea {
    max-width: 280px;
}

Nothing complex, though it’ll let us at least build a workflow around them.

There are a couple of key tasks we want to perform here:

  1. Grab all less files and compile them over to css
  2. Compress that css
  3. Push them all into a single file in our dist folder

Thankfully, the ‘gulp-less’ plugin performs the first two tasks, and we have already achieved the other for our JS so it’s just a repeat of those steps.

Integration into Visual Studio and tying it all together

We now have a basic working build that we can add to as and when our process demands – node and the node package manager (npm) have a massive ecosystem of libraries to support all sorts of tasks (generaily, gulp- prefixed for gulp related build tasks), so you can start to build from this point forward.

Key thing now is tying this workflow into Visual Studio, and this is where the cool happens.  The Task Runner Explorer gives us a lot of extensibility points.

image

Each of these tasks/sub-tasks can be right clicked and ran as you would do from the command line easily, but you also have a nice option to ‘bind’ certain actions in Visual Studio to steps within your grunt build.

E.g.

image

In this instance, we have bound our ‘clean’ gulp task to a ‘clean solution’ within visual studio.

Tying it all together – watching the solution

Web essentials was awesome at monitoring your work real time and updating bundled files (both less and js) into their respective outputs, but thankfully, gulp comes to the rescue in the guise of ‘gulp-watch’ – this is a highly configurable module that allows you to perform actions on changes to files.

Thankfully, now that we have all of the other tasks, the watch workflow is simply a matter of matching up targets to watch, and tasks to run when things happen to those targets.

var watch = require('gulp-watch');

gulp.task('watch', function () {
	gulp.watch('bower_comonents/**/*', ['vendor-scripts', 'vendor-css']);
	gulp.watch('Content/**/*.less', ['css']);
});

gulp.task('default', ['clean', 'vendor-scripts', 'vendor-css', 'css', 'watch'], function(){});

Once we have that, we can go back to the task runner explorer, right click the ‘watch’ task, and set it to run on solution open.

We now have our solution in watch mode permenantly and any changes to our less or the vendor scripts will trigger the appropriate tasks.

What’s next?

We’ve solved the problem (compiled css/js needing to be in our repo with web essentials), so the next steps really are incorporating this gulp build task into our CI server (TeamCity), though we’ll leave that for a follow up post.

Now that we have a whole set of automation going, we may as well re-introduce linting/hinting of our less and javascript too – some configuration will be needed here to ensure we’re happy with the outcomes, but fundamentally the ‘right thing to do’.

Testing our JS workflow is the next natural step, and there are plenty of gulp+other task runners to sit within this workflow that will let you validate your scripts either at build time or at save.

Yeoman hangs on windows – with a fix

Thought I’d quickly write this up as @kevinawalker and I had a mare with it yesterday on our windows boxes.  I suspect it’s because I’d attempted to setup yeoman in the past before there was a nice npm install pathway, coupled with the lack of dependecies my machine (I installed an up to date ruby+python in between break and fix).

Symptoms

npm install –g yo

would appear to work and give solid feedback that everything appeared tickety boo.  All PATH variables certainly indicated it would work, and ‘yo’ was discoverable in the path.

That said, typing anything other than yo –version would hang and never return (requiring a ctrl+c to break out of it).

When oldschool debugging through it (console.log for the win), turns out cli.js in the %APPDATA%/roaming/npm/node_modules/yo/cli.js was haning on line 76:

env.lookup()

I didn’t follow down the pathway, though when npm installing yo on the mac it went through no bother.

npm uninstall –g yo

then a re-install didn’t help, whether or not we cleared the npm caches in between.

Solution

I still don’t know which magical combination of the above really worked (it may be that updating ruby/python between the old install and new was key, I can’t be sure) but the following steps fixed for both @kevinawalker and I:

  1. npm uninstall –g yo
  2. explorer window to %APPDATA%/roaming/npm-cache/
  3. delete ‘yo’ folder
  4. npm install –g yo

After that, all was well with the world.

Good luck, hope this helps someone!

Velocity Conf Europe 2013 – How to utterly inspire in three short days

The past 3 days have seen me attend VelocityConf Europe 2013 which (as the sub-title suggests) focuses on Web Performance and Operations.

Talks I attended can be seen here, though thankfully they seem to record all sessions, so if you missed it they’re available from here.

I had the chance to hangout with the @toptabletech guys (http://tech.toptable.co.uk/) (@ryantomlinson has just joined them and he moved to them from working with me), and they’re all top blokes – very clever, and clearly care about what they do.

tl;dr

Without a doubt one of the best conferences I’ve attended – the mix between operations talks (though often these were given a very devops slant) and web performance really did tick all of the boxes.  It feels very much like my learning time will be consumed by some of the approaches, tools and techniques I’ve seen covered over the past few days, and I remain utterly excited about putting some of this into practice.

It does make me question some of the cultural aspects within my own organisation – something I will endeavour to at least attempt to communicate effectively upon return – there are a lot of things we could be doing better (myself very much included).

Overall, not that my passion was lacking anyway, though I’m entirely re-fired up around the areas I’ve seen talked of – monitoring/metrics, continuous integration/deployment, testing all the things, and automation, with that constant backnote on the cultural.

I became acutely aware of just how narrow my scope of development was (.net developer/PC based), and time and again a lot of the tooling shown while it likely worked on windows ‘ok’, was better geared up to either a mac os/linux background – the mac to PC ratio was scary, and it’s certainly something where I’m now going to experiment with mac as a dev machine (VM’ing into windows for the .net stuff).

I’ll cover some of the details on some of the talks I attended, though obviously covering every talk from 3 days worth is going to see at least some repetition so apologies if I miss anything/anyone out.

The below is as much so that I have all of the pointers in one place to the stuff I want to look at, though hopefully others will find it useful.

Responsive Images – Yoav Weiss

Cracking start, Yoav highlighted 72% of responsive websites serve the same resources to all form factors (we use picturefill).  I liked the look of http://sizersoze.org as a tool to highlight what you were doing at different breakpoints (in terms of savings to be made, etc.)

He highlighted mobify.js, which although a clever implementation, feels like an overwhelming hack to get around some of the limitations currently in play on browsers/http.

First mention of http://worldwidepagetest.com/ in this session too.

Be Mean to your code with Gauntlt – James Wickett

I moved from the more ops’y (TCP tuning/TLS perf etc.) talk into James’ security talk, and I wasn’t disappointed.

Gauntlt provides a means of automating a number of other attack tools and overall was the first thing where I thought ‘getting that into our build is essential’ – another talk where ‘it’s easier on a mac’ (probably the first, not the last).

Making Government Digital Services Fast – Paul Downey

Loved this talk – really nice to see how effectively these guys release and how the mindset shift was entirely around ‘what does the user want’.  Their ‘dark release’ rollout worked well, and it was one of the first talks (though again not the last) that highlighted how important instrumentation was – how do you know you’ve been successful (or otherwise) if you don’t have figures backing it up.

Stand Down Your Smartphone Testing Army – Mitun Zavery

I mention this not only because it was a good talk, though I really must have a look and play with http://www.deviceanywhere.com/.  Really nice little tool.

Testing all the way to production – Sam Adams

Loved the ‘continuous delivery’ from day 1 approach, and the mindset that each commit I make ‘I believe this code is safe to go into production’, though obviously again the monitoring metrics come in, and it’s the pipeline’s job to prove that statement wrong – strong enough pipeline builds confidence that you’ve caught ‘all the things’.

They do a lot of ‘in live’ testing, though their isolation model seemed to work really well – something I have to investigate.

Global Web Page Performance – James Smith

Although the demo didn’t go great for James, I’d used the site the day before as it was mentioned in one of the workshops and it’s a really nice abstraction over http://webpagetest.com – certainly useful.

HTTP Archive, BigQuery and you! – Ilya Grigorik

This was one of those ‘holy shit!’ demos – taking HTTP Archive data and making it accessible/queryable – see (and play with) http://www.igvita.com/2013/06/20/http-archive-bigquery-web-performance-answers/ – incredible.

Gimme more! Enabling user growth in a performant and efficient fashion

Some useful stats in this great talk – by 2017 there’ll be 5.2 billion mobile users, making more than 10 billion connections!  Mobile video will increase 16 fold between 2012 and 2017.

New Image Formats

Images make up 61% of page bytes – 65% of page bytes on mobile!  The encoding techniques we have in place are in some cases 15 years old.  WebP (less supported) and JPEG eXtended Range (JXR) look to be the next big thing in image compression and both although not heavily supported right now, if you have in place content-negotiation/browser sniffing, you could save considerable bandwidth.

Code Club – John Edwards

I love this – https://www.codeclub.org.uk/ – teaching children to code in a structured/supported way, and volunteering your own time to help.  I will be investigating this to see how best I can fit in – time is key I guess (support from employer etc.) but I really love the concept so I hope I can get involved in some way.  John Edwards did an amazing job of presenting it, and the video (http://www.youtube.com/watch?v=Ci3hY83rUwU) had me both chuckling and incredibly emotionally moved.  Great cause.

General Thoughts – Culture

A number of the talks focussed around the cultures within the organisations that we work, and in how the culture almost entirely underpins how and what you achieve and the direction of work. 

One of the best talks of the conference for me was given by John Willis, entitled ‘Culture as a Strategic Weapon’, which focussed on some of the core tenets of successful devops (CAMS – Culture, Automation, Measurement, and Sharing).

It’s made me more determined to keep pressing on with both working with, and encouraging new directions within my own organisational culture – as he said, ‘If you can’t change your culture, change your culture’ and the immortal words of ‘get the hell out of dodge’.  Working towards a better organisational culture feels like the right fight to be having, but this one talk has generated me more inspiration than any other single talk at the conference.

When seeing how effective some of the guys I talked to were being with things like ‘30% time’ and how much other organisations invest in their staff, it very much feels like there are lessons I can bring home here.

General Thoughts – Tooling

There are so many cool tools – too many to name, though the links I’ve put above are a good starter – there are so many people working on tools to both monitor, test and graph ‘all the things’ so that we get closer and closer to reliable, repeatable, understandable and maintainable releasing.

Closing Thoughts

I thankfully have a solid team of developers where I work who will be very keen to be involved in this.  We’re not bad, we do automate a lot of our build pipeline, though we don’t have enough monitoring/metrics in place. 

The conference has entirely re-invigorated me and as I sit here writing up, the thing exciting me most is ‘where do I start’ – I look forward to the playtime!

This was a great conference, and was great to be around likeminded, passionate people who were all about sharing how they got to where they are, where they want to be, and how they intend to get there.

Oh, and thanks to the facebook staff who took us to the pub on thursday night – I really enjoyed the talk with you guys and learned an awful lot!

 

Bring it on 🙂

We’re hiring (again!)

We’re looking for 1 developer to join a growing team in Sunderland who support and build software for tombola bingo – currently the UKs largest online bingo site.  We’ve branched out into italy, spain and elsewhere which has seen significant expansion to the team.  We are looking to place the developers within the web team.

There are 13 of us on the web team, and we are developers who love to be good at what we do – we’re passionate about delivering quality and are looking for likeminded people.

We don’t score too badly on the joel test or by others’ standards

  • We use subversion for source control
    We realise that some people would have us apologise for this, though we’re going to debate the use of dvcs soon and svn works (most of the time) for us
  • We have made our own custom build scripts with msbuild
    And although we don’t yet practice continuous deployment, we’re not that far off.  We’re also playing with psake as a replacement for msbuild. 
  • We don’t make daily builds, but we do have team city
    We use it actively for deployments/testing/automated smoke testing and are constantly improving, looking at code quality metrics etc.
  • We do have a bug database and we try to fix bugs before writing new code
    You know how it is… Winking smile
  • We employ scrum/kanban to manage our projects
    We do dailies, we work to (generally) two week sprints, we use scrumwise and trello to help with the overall picture and we’re big fans of the transparency and flexibility of agile.
  • We do regular code reviews and mentoring
    If you have a skills shortfall, chances are someone has it and will be willing to support
  • We talk a lot
    We all get stuck, we all need to bounce ideas off people, we all need opinions from time to time.  As a team, we talk to each other a lot to resolve difficulties or just get a perspective on potential solutions
  • We grok good software design principles
    We may not always apply all of the SOLID principles, and our code isn’t littered with “cool design pattern X”, but we know how and when to apply these and our codebase stands up well to scrutiny
  • We have people who have personal/play projects, and we love that
    Time is always hectic in the office, though we do our best to support anyone with an idea and we love that we have devs who are passionate about their career

the role

The role is primarily for C# asp.net MVC developers with the usual skillset: asp.net MVC 4 (or 5, 3 or 2!), decent HTML/javascript/CSS skills, decent SQL/NoSQL skills, and some understanding of some of the above bullets would make you stand out. 

With the expansion of the company, there are always opportunities to get into new technology too, and we’re always playing with new stuff – HTML5 for games is a hot topic at the moment (and all of the associated technologies), social media (ewww, we all hate that term, but you know what we mean!).

The only real caveat aside from the above is that you must be passionate about what you do – you will obviously want to make good software, and want to work with people who enjoy doing the same.

Salaries for the roles are competitive (and negotiable) and based upon experience.

get in touch for a chat

If any of the above sounds interesting, or you have any questions, please get in touch.  We’re pretty nice guys/girls and if that’s as far as it goes, at least we’ll have had a chance to meet you and you us Smile

Contact either myself, Terry Brown – Project Lead, @terry_brown, 07968 765 139)

or Ian Walshaw – Operations Manager, @ian_walshaw1973, 07850 507 629)

No Agencies

Guys, we have a preferred supplier list (who will also be looking for the above), please don’t contact us if you’re not on it – it’ll only piss us off.

Ryan Tomlinson : ITeamLead, ISolutionsArchitect, IPassionateDeveloper

I thought I’d write up a post about a member of my team, Ryan Tomlinson.  I’ve had the pleasure to work with him for the past 2 years, when he joined our employer as a senior software developer.  Very quickly he joined the projects team and after a period working on other projects took up lead on the implementation of our Spanish website.  It was here that Ryan really started to show the skill set that he had, and he helped bring into tombola an awful lot of the project management practices and software architecture that are very actively followed today.  When I was awarded the web team lead role it was only a gnats hairs breadth between us on which would have been best for the role, and in all honesty we both were ‘best’ for the role, just different.  He has since gone on to work on, and lead, multiple projects at tombola, always bringing his ‘best practice’ approach to each.

I’ve never written up a post about another developer I’ve worked with previously, though as Ryan now moves on to a team lead role at TopTable, I felt compelled to write this one.

We have spent the past two years with a relationship bordering on occasional violence because of the insults that we aim at each other, though fundamentally both know it is only achievable with the absolute upmost respect for the other – sarcasm has been a solid comedy mechanism between us, and I shall sorely miss it.

We have challenged each other during his time here on an almost daily basis, and both have grown better as developers, architects, and leads because of it.

He is without hesitation one of the best developers I have ever had the pleasure to work with – his insight, his motivation, his drive, and his experience has brought a massive amount of value to tombola over the past two years, and TopTable have gained an overwhelmingly solid team lead.

Really sorry to see you go mate.

You can see more at Ryan’s blog, twitter, and github

Creating a drop down list from an enum in ASP.NET MVC

Thought I’d share some work we’ve done in our MVC projects to ease the generation of drop down lists from enum types which makes life a hell of a lot easier for us when working with enums in views.

The basic premise focuses around the method below which is represented all over the web really (a lot of people seem to have come up with the solution at around the same time it seems) which is given an enum:

public enum UserType
{
	Visitor = 1,
	NonDepositor,
	DepositedOnce,
	DepositedTwice,
	Regular,
	LapsedRegular,
	LapsedNonDepositor
}

We can create a simple enum to select list convertor with the following:

public static SelectList ToSelectList<TEnum>(this TEnum enumObj)
{
	var values = (from TEnum e in Enum.GetValues(typeof(TEnum))
					select new { ID = e, Name = e.ToString() }).ToList();

	return new SelectList(values, "Id", "Name", enumObj);
}

Caveat: I didn’t invent this, it’s a pattern that’s published in a lot of places (stack overflow and other peoples blogs).

Making it look pretty

This may well work fine for a lot of your use cases or indeed for simple admin/internal systems, but our use cases dictated we extend this a little.  First and foremost was getting friendly strings out of this for the display value (our users like Words Separated With Spaces – curious that).

You could easily go with a simple regex on the ‘ToString()’ part of that code – something like:

public static string PascalCaseToPrettyString(this string s)
{
	return Regex.Replace(s, @"(\B[A-Z]|[0-9]+)", " $1");
}

And your call in the ‘ToSelectList’ method above would just be ‘ToString().PascalCaseToPrettyString()’ (for info: the regex above will take all uppercase characters or collections of numbers that aren’t at a word boundary and put a space in front of them).  This would give us something like ‘Deposited Once’ as opposed to ‘DepositedOnce’

Again, this may well suit exactly what you want, but what if the description you want to show to the user really doesn’t match what you want as the enum value.  For this, we look to the [Description] attribute and would decorate up our enum as follows:

public enum UserType
{
	[Description("Visitor (Not logged in)")]
	Visitor = 1,
	[Description("Non-depositing player (Created account, no deposits)")]
	NonDepositor,
	[Description("Single depositing player")]
	DepositedOnce,
	[Description("Twice depositing player")]
	DepositedTwice,
	[Description("Regular depositing player (Has 3 or more deposits)")]
	Regular,
	[Description("Lapsed Regular (Not logged in for the past 12 weeks)")]
	LapsedRegular,
	[Description("Lapsed Non-Depositor (Not deposited, not logged in for the past 12 weeks)")]
	LapsedNonDepositor
}

In this case we can simply extend our ‘PascalCaseToPrettyString’ concept a little further with:

public static string GetDescriptionString(this Enum val)
{
	try
	{
		var attributes = (DescriptionAttribute[])val.GetType().GetField(val.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);

		return attributes.Length > 0 ? attributes[0].Description : val.ToString().PascalCaseToPrettyString();
	}
	catch (Exception)
	{
		return val.ToString().PascalCaseToPrettyString();
	}
}

This will attempt to grab the DescriptionAttribute from the enum value if there is one.  This will handle both situations (with and without Description attribute) nicely, and falls back to at least something that looks nice to the user if a description attribute isn’t present).  Our ‘ToSelectList()’ method will then just update to call .GetDescriptionString()’ instead of ‘ToString()’ for the value  (you will have to change the enum call like so):

public static SelectList ToSelectList<TEnum>(this TEnum enumObj)
		{
	var values = (from TEnum e in Enum.GetValues(typeof(TEnum))
					select new { ID = e, Name = (e as Enum).GetDescriptionString() }).ToList();

	return new SelectList(values, "Id", "Name", enumObj);
}

And we’re left with:

image

So far so good – what next?

The next steps are really edge cases, though it was useful to extend the helper in our use cases to deliver flexibility in all cases where we needed it.

Filtering

There are situations where you want to include only those options that are applicable based upon some other selection parameter or indeed some particular use case.  For this we can use a Func delegate along the lines of:

public static SelectList ToSelectList(this TEnum enumObj, Func predicate = null)
{
	IEnumerable values = (from TEnum e in Enum.GetValues(typeof(TEnum))
									select e);

	if (predicate != null)
		values = (from TEnum e in values
					where predicate(e)
					select e);

	var outputs = (from TEnum e in values
					select new { ID = e, Name = (e as Enum).GetDescriptionString() });

	return new SelectList(outputs, "Id", "Name", enumObj);
}

And in our views we can do something along the lines of:

<p>@Html.DropDownListFor(model => model.BankBalanceState, Model.BankBalanceState.ToSelectList( x => x != UserType.LapsedNonDepositor &&
				                                                                                    x != UserType.LapsedRegular))</p>

Adding ‘Please select’ as the first option

A simple one, though it saves you from having to jump through a few hoops if it’s important to have the ‘please select’ option at the top of the list.  This one requires a little more change to our helper method:

public static SelectList ToSelectList(this TEnum enumObj, Func predicate = null, bool addPleaseSelect = false)
{
	IEnumerable values = (from TEnum e in Enum.GetValues(typeof(TEnum))
									select e);

	if (predicate != null)
		values = (from TEnum e in values
					where predicate(e)
					select e);

	var outputs = (from TEnum e in values
					select new SelectListItem { Value = e.ToString(), Text = (e as Enum).GetDescriptionString() });

	if (addPleaseSelect)
	{
		var pleaseSelect = new List { new SelectListItem { Text = "--- please select ---", Value = "" } };
		outputs = pleaseSelect.Concat(outputs).ToList();
	}

	return new SelectList(outputs, "Value", "Text", enumObj);
}

Which leaves us with:

image

Shuffling the values

Another edge case though one that was useful to us in a number of situations was the shuffling of the values within the list.  We achieved this using a simple extension method:

public static ICollection ShuffleList(this ICollection list)
{
	return list.OrderBy( x => Guid.NewGuid()).ToList();
}

And included it in the updated ToSelectList like so:

public static SelectList ToSelectList(this TEnum enumObj, Func predicate = null, bool addPleaseSelect = false, bool shuffleList = false)
{
	IEnumerable values = (from TEnum e in Enum.GetValues(typeof(TEnum))
									select e);

	if (predicate != null)
		values = (from TEnum e in values
					where predicate(e)
					select e);

	if (shuffleList)
		values = values.ToList().ShuffleList();

	var outputs = (from TEnum e in values
					select new SelectListItem { Value = e.ToString(), Text = (e as Enum).GetDescriptionString() });

	if (addPleaseSelect)
	{
		var pleaseSelect = new List { new SelectListItem { Text = "--- please select ---", Value = "" } };
		outputs = pleaseSelect.Concat(outputs).ToList();
	}

	return new SelectList(outputs, "Value", "Text", enumObj);
}

Which is called from the view like so:

<p>@Html.DropDownListFor(model => model.BankBalanceState, Model.BankBalanceState.ToSelectList(shuffleList: true))</p>

Other extensions to this?

We’ve come up with a few more updates to this – one to force presentation via the enum numeric value (oddly in an enum, -1 is rendered after 1 and this isn’t always what you’d hope for).  We’ve also updated it for our multi-tenant websites to support localisation of enum values (though there’s enough work in this to provide an entirely separate blog post).  We’ve also added an optional parameter to ignore the current value of the enum (default to the first value in the select list rather than the selected enum) – again, an edge case, though I’m sure folks can see use cases themselves for this.

Hopefully that was useful – had been meaning to write it up for a while now (we’ve been using it in production now for over a year and it performs quite happily and there seem to be no bottlenecks/issues with it).

Grab the code

I’ve put the finished solution onto github if anyone wants to grab it and modify it themselves.  If anyone has suggestions on improvements feel free to send a pull request.