Why feature switches?

The key feature of Dolstagis.Web is that it builds the concept of feature switches and Branch by Abstraction right into its core. To anyone who recalls the position that I adopted three years ago in The Great Feature Branch Debate, this will no doubt come as a bit of a surprise. Am I jumping the shark here?

Not really. I may have been objecting at the time to the black-and-white “feature branches bad, feature toggles good” line being adopted by Martin Fowler and his ThoughtWorks colleagues, but my own opinion is somewhat more nuanced than the polar opposite of “feature toggles bad, feature branches good.” There are actually a lot of clever things that you can do with feature toggles:

  • You can set them to flip at a specific date and time, for example, if you want to launch something at a conference.
  • You can have them go by IP address. For example, country-specific features.
  • You can use them for A/B testing.
  • You can use them to turn off features and degrade your site’s performance gracefully under load.
  • You may occasionally have a feature that needs to be turned off in order to perform a specific upgrade.

The problem with feature switches is that when they are used as an alternative to branching and merging, you are regularly deploying code into your production environment that you know for a fact to be buggy, immature and incorrect. If your feature switches aren’t properly architected, this can end up being exposed to the general public — with disastrous results. Breaking your tasks down into small user stories can help, but this is not always the case.

The commonest mistake here is that your feature switch doesn’t switch everything. On an ASP.NET web application, for example, it may switch out your controllers, or your routes, but you will still have the same views, the same JavaScript, the same CSS and the same images and other static assets available for both the “on” and “off” states. It’s difficult to turn static assets on or off when by default they’re all served up by IIS from your web application’s filespace.

Dolstagis.Web gets round this problem quite simply by requiring you to expose your static files and your views explicitly in your feature definition classes. If it hasn’t been added, it won’t be shown: it’s as simple as that. In fact, you aren’t even limited to using your application filespace: you could just as easily include your static files and views as resources within your assembly. You can even have the feature that you are toggling in a separate assembly altogether, and modify your build process so that your production version doesn’t even have a copy of the immature and buggy code.

Of course this doesn’t guarantee you that you’ll get your feature switches right, and there are still ways in which you can get them wrong, but hopefully this approach will help to make it easier to avoid running into problems.

Dolstagis.Web 0.3 is out

The latest version of my hobby project has now been released to NuGet for anyone who wants to tinker.

When I first started it off a year ago, it was mainly an experiment to see just how long it would take me to write a minimum viable alternative MVC framework. I was mainly inspired in this by tinkering with some of the alternatives to ASP.NET MVC such as NancyFX, FubuMVC and so on, but also because I’d run out of ideas for something to keep me entertained on my daily commute into London. In the end it took me about a month or so.

Of course, there’s a vast difference between “minimum viable” and “actually usable,” and all I was interested in at the time was a basic proof of concept, so once I had the bare minimum up and running, I decided to just park it. But then back in August I was inspired to take it a bit further, so since then I’ve been doing a bit more work on it, and now I think I’ve got it to a point at which I can realistically start dogfooding it on another hobby project.

Over the coming weeks I’ll be blogging about some of the features I’ve been building into it, but for now here’s a summary of what I’ve been working on over the summer:

  • Everything is now OWIN-based rather than going through a custom abstraction layer based around HTTP handlers and modules.
  • The feature switching API has now been implemented. You can base your features switchable on a configuration setting, or a go-live date, or you can even write your own custom feature switches based on various aspects of your request, such as user agent or IP address.
  • Session state, cookie handling and a rudimentary user authentication mechanism are now available.
  • The routing engine has been rewritten. Each Feature now gets its own route table, which can be switched out for a custom implementation if the out-of-the-box option isn’t suitable for your needs.
  • I’ve taken a first stab at implementing some basic model binding.
  • Version 0.1’s Modules have been renamed to Features for consistency with the concept of feature switches.

Here are some ideas that I’m thinking of implementing in due course:

  • A Razor view engine adapter
  • Anti-XSRF protection
  • A Ruby on Rails-style “message flash”
  • An asset pipeline for bundling and minification
  • Some form of content negotiation
  • An A/B testing plugin built around the feature switch API
  • The ability to declare dependencies between features

It’s still not quite production ready yet, so it’s best to stick to breakable toy projects for now. Suggestions are, of course, always welcome.

So I’ve built my own ALT.MVC engine

(ALT.MVC means any MVC-style framework for .NET that was not written by Microsoft.)

For the past few weeks, my commute-time hobby project has headed in a completely new direction, and I’ve been working on a completely new MVC framework for .NET. I was inspired to do this mainly by some of the other offerings in the ALT.MVC space, such as NancyFX, FubuMVC, Simple.Web and OpenRasta, and I was curious to see just how much effort is involved in getting a minimum viable framework up and running. About two weeks, it turns out, plus about the same again to add some spit and polish, though the end result is pretty spartan. It doesn’t (yet) have any kind of model binding, or validation, or CSRF protection, or authentication and authorisation, or even session management. But these will come in due course.

Different MVC frameworks have different emphases. ASP.NET MVC is generally designed to appeal to as broad a constituency as possible. As a result it’s a bit of a jack-of-all-trades: it does everything under the sun, most of it passably, some of it awkwardly, and none of it brilliantly. FubuMVC is designed for people who are steeped in Clean Code and design patterns, and who have a degree in Martin Fowler. NancyFX is built around the “super-duper-happy path”: its aim is to keep things as low-ceremony and low-friction as possible. WebForms was designed to ease the transition to web development for traditional VB and Delphi developers, who are used to event-driven drag-and-drop RAD programming. The result is a complete untestable mess, simply because the web doesn’t work that way.

The key emphasis behind my own MVC effort is modularity. Most MVC frameworks encourage a fairly monolithic design to your application. Sure, they may be extensible using IOC containers and so on, but you’ll have to jump through several hoops in order to implement feature toggles, or A/B tests, or plugin frameworks, and even then your solution will be partial at best. My MVC framework, on the other hand, is built entirely around the concept of pluggable, switchable modules. This allows for some unique features. For example, you can have your static files—your CSS, JavaScript and images—switchable along with their corresponding server-side components. Turn off the feature that serves up /my/secret/script.js and it will give you a 404 when you try and access it in your web browser.

Anyway, enough of the sales pitch, let’s take a look at how it all works. A module looks like this:

public class HomeModule : Dolstagis.Web.Module
{
    public HomeModule()
    {
        AddStaticFiles("~/content");
        AddViews("~/views");
        AddHandler<Index>();
    }
}

This tells us that all files within your content folder should be served up as static files; that your views are all in your views folder, and registers a handler called Index to handle your home page. Handlers might look something like this:

[Dolstagis.Web.Route("/")]
public class Index : Dolstagis.Web.Handler
{
    public object Get()
    {
        var model = new { Message = "Hello world" };
        return View("~/views/hello.mustache", model);
    }
}

This class handles all GET requests for the home page with the view at views/hello.mustache using an anonymous class for our model. I’m using Nustache as the default view engine at present; since these are the same as Mustache views, you can easily use them on both client and server. Note that you can only have one route per handler: this is by design as it is much closer to the Single Responsibility Principle, and reduces the number of dependencies that you have to inject into your controllers that end up not even being used on most of your requests.

As I say, it’s still very much early days yet, and it’s not production ready by a long shot, but there are several things I’ve got planned for it. If you fancy getting involved with something new in the ALT.MVC space, then I’m always open to suggestions and pull requests. You can find the source code in my Dolstagis.Web repository on GitHub, or drop me a line in the comments below or to @jammycakes on Twitter.

Dolstagis: my pet project

I thought it would be a good idea to say a bit about my pet project that I’ve been working on over the past few months on my daily commute.

Round about September or October, I ended up reading Patrick McKenzie’s blog, kalzumeus.com, where he was talking about how he managed to start up a business from his hobby programming project, Bingo Card Creator, on no more than five hours a week. Seeing as I spend twice that sitting in trains, otherwise doing nothing other than playing Angry Birds, staring out of the window, reading xkcd, or sleeping, I thought that something like that would be a much more profitable use of my time.

Only one problem: I didn’t have any ideas. Or rather, I had too many of them. At any one time I will have half a dozen ideas for a web application floating around in my head, but none of them have yet risen above the others. Nevertheless, I figured that there’s a lot of ground work to be getting on with before you get your big idea, so I typed hg init, cranked up Visual Studio, and got going. I’d also heard the story of how Flickr got started: how it was originally intended to be an online game but ended up as a photo sharing service almost by accident, and I figured that perhaps one particular idea would emerge out of the melting pot as I get working on it.

So far I still haven’t had my big idea, but I have ended up with the makings of a web application framework for ASP.NET MVC. Its intentions are similar to those of Django, the Python web application framework, in that it’s a “batteries included” framework which will eventually offer all sorts of building blocks for your own ASP.NET applications: dependency injection, unit and integration testing, NHibernate session management, asset bundling and minification, user authentication and authorisation, an admin section, comments, and eventually even integrating unit testing for JavaScript into your build process.

It’s also turned out to be a bit of a playground for me to experiment with new things, and to try out some of my ideas and hypotheses about patterns and practices to see if they’re any good. So far, I’ve tried (and rejected, for now at least) CoffeeScript, the Web API, and not using the Repository pattern.

Since I suck at coming up with cool names for things, I’ve called it “Dolstagis” for now, after an in-joke that was current among some of my colleagues and myself at work a few years back. I’ll no doubt write a bit more about it over the coming weeks and months, and the lessons that I’ve learned along the way, but in the meantime, if you want to see what it looks like, I’ve posted the code on GitHub.