What should a .NET renaissance look like?

Aaron Stannard has an interesting blog post in which he talks about all the different ways in which the .NET scene has improved in the past few years. There’s certainly a lot going on in the Microsoft ecosystem to get .NET developers excited, and he mentions six areas in particular where this is evident:

  1. The decoupling of .NET from Windows
  2. The new-found focus on CLR performance
  3. Moving .NET’s tooling to a cross-platform model
  4. The .NET user base is embracing the OSS ecosystem as a whole
  5. The direction on .NET development is pushing users further down into the details of the stack
  6. Microsoft’s platform work being done out in the open.

Now these all look pretty exciting, but the litmus test of whether we are seeing a .NET renaissance is whether or not it can attract people who have “left .NET” back into the fold.

I have had little involvement in .NET myself over the past year, since I moved onto a team doing DevOps work on AWS for mostly LAMP-based projects a year or so ago. While I wouldn’t describe myself as having “left .NET” never to return, there is still one very important thing that needs to happen before I would consider it an attractive prospect to pick up that particular baton again.

The .NET community as a whole needs to provide evidence that it is becoming more open to options from beyond the Microsoft ecosystem.

When you move beyond the .NET ecosystem, one of the first things you find is that there is much more cross-flow between the different technology stacks. Developers are much more likely to be familiar with (or at least, willing to try out) other languages outside their usual ambit. Ruby developers won’t think twice about getting their hands dirty with Python, or Go, or Scala, or even C#, if the need arises. Any solution that gets a good enough reputation and meets your business need will be up for consideration — ElasticSearch, DataDog, Terraform, Consul, you name it. Different languages are mixed and matched — and all the more so with the increasing popularity of microservice-based architectures.

By contrast, for many years, most .NET developers have shown very little interest in anything beyond the Microsoft ecosystem. In fact, some of them have even regarded other technology stacks with suspicion if not outright hostility. There’s a widespread attitude in many .NET teams in many companies that unless something is included out of the box in Visual Studio, documented first and foremost on MSDN, promoted by Microsoft MVPs, and certified by Microsoft examinations, you’ve no business whatsoever paying the slightest bit of attention to it. If you’ve ever been told to do something a certain inefficient and cumbersome way for no reason other than That Is How Microsoft Wants You To Do It, or been given a funny look for suggesting you use Python for something, you’ll know exactly what I mean.

Nowhere was this more evident than in the Silverlight community. The reason why Silverlight died and HTML5 took over in its place was that browsers and platforms which were outside of Microsoft’s control — starting with the iPhone and the iPad — started blocking it. Yet Silverlight developers almost unanimously put the blame for Silverlight’s demise at Microsoft’s feet. The fact that there were decisions being made by other browser manufacturers that had to be considered didn’t even seem to enter their minds.

When your team has a healthy level of interaction with other parts of the software development community, you start to see many, many benefits. You learn from other people’s mistakes as well as your own. Your attention is drawn to solutions to problems that you didn’t realise were problems. You get an element of peer review for your best practices. You get a better idea of which tools and technologies are likely to stick around and which aren’t. On the other hand, with a paternalistic, spoon-fed attitude, you end up turning up late to the party and very often completely misunderstanding the processes and tools that are being suggested to you. It’s amazing to visit the ASP.NET architecture forum and see how many .NET developers still cling on to horrendous outdated “best practices” such as n-tier, business layers that don’t contain any business logic, or misguided and ultimately futile attempts to make Entity Framework swappable for unknown mystery alternatives.

There are of course many .NET teams that get these things right, and that do successfully engage with teams from elsewhere. But I’d like to see a whole culture shift right across the entire .NET ecosystem. I’d like to see it become commonplace and widespread for .NET teams to go beyond embracing just those bits and pieces from elsewhere that get Microsoft’s imprimatur, such as Git, or bash on Ubuntu on Windows, or Angular.js. I’d like to see a greater willingness to try tools such as make or grunt instead of MSBuild; Terraform instead of Azure Resource Manager; ElasticSearch/Logstash/Kibana instead of SCOM; and so forth. I’d like to see a much greater willingness to augment C# codebases with utilities and helpers written in Python, Ruby or Go where it makes sense to do so.

I’d like to see them fully embrace twelve factor apps, configuration settings in environment variables rather than the abomination that is web.config, container-based architecture, and immutable servers treated as cattle rather than pets. I’d like to see innovations in software development tooling and techniques getting adopted by the .NET community much faster than they have done up to now. You shouldn’t have to wait for Microsoft to take notice and give their imprimatur before you start using tools such as Git, Docker or Terraform, when everyone else has got there already.

Once we get to that point, we can truly say that we are seeing a .NET renaissance.

How to keep lab notes as a software developer

My decision to start keeping lab notes, research scientist style, in my work a couple of months ago has started to pay off. By constantly writing down everything I do, when I run into trouble with what I’m doing, I am able to go back over my notes quickly and easily and see exactly what I did. As well as making for a much more disciplined approach to working, it’s helped to clarify my thoughts, and to avoid situations where I might end up spinning my wheels rather than getting to the heart of the matter.

Here are some tips.

1. Choose the most low-friction solution you can get your hands on.

It is very important, especially in the early days when you are just getting used to the discipline, that you choose a solution that is as frictionless as possible.

You are establishing a habit. Those who study these things tell us that it can take several months for a habit to become established to the point at which it seems easier to do it than not to do it, and until you get to that point, anything that tempts you to take shortcuts needs to be resisted and ruthlessly eliminated.

For me, I find that Microsoft Word works fine. Our project manager tried to persuade me to use Jira, so as to have everything in one place, but Jira’s quirky markup syntax, combined with having to type into a tiny input field in a web form, made this a frustrating experience. It’s better to write it in Word and then copy and paste into Jira later if that is what is needed.

2. Write down everything you do, as you do it

Lab notes work best if you write down what you’re going to do before you do it rather than after the fact. In that sense it’s a bit like test-driven development: write your tests first, then write the code that makes them pass.

This has two benefits. First, it is more accurate and more complete, because you’re less likely to miss out details. Secondly, it has the benefit of forcing you to think clearly about what you’re going to do.

This also makes your lab notebook a record of your stream of consciousness. As such, you will be spending at least as much time in your lab notebook as you are in Visual Studio, or vim, or whatever your IDE of choice happens to be. This is another reason why you need to go for the lowest-friction solution you can get your hands on: even small amounts of friction will chafe at you, and will tempt you to ease off and take shortcuts.

When you’re waiting for a slow compilation or test run to complete, use the time to write down what you’re going to do next. This is a far more effective use of the resulting downtime than reading Reddit or Hacker News, and it’s also a whole lot easier to context-switch back to what you were doing once you’ve finished.

3. You can not be too detailed.

The purpose of lab notes, as with any other form of auditing, is to answer questions. For example, one such question that we all ask, time and time again, is, “I encountered this error before. What did I do to fix it?”

So for instance, if you encounter an error message, copy and paste the message into your notes. Write down exactly what steps you took when it happened. Write down exactly what steps you need to take to reproduce the error. Write down exactly what tests you carried out in order to troubleshoot it, and exactly what the error messages were. Write down any relevant Google searches, and copy and paste the URLs of the web pages that they led you to.

4. Write down your train of thought when you’re planning and designing your code.

Use your lab notes as a scratchpad to plan what each script, each method, and each command should do. How does it store state? How does it identify if it’s been run before? What should it prompt the user for, how, and when? What should the default values be? Why did you give things the names that you did?

It’s actually a lot easier to write code this way, because you’re holding less information in your head at once, and it’s much easier to pick it up again if you break off. It’s also easier to comment your code, because you can just copy and paste some of your design decisions into your source code or your wiki if necessary.

5. Don’t worry too much about making your notes look good.

You aren’t writing documentation, or a final report, or a thesis, or a sales pitch, or a blog post. You are only writing rough notes to remind yourself, or keep your colleagues up to date, about what you’ve done.

Just write it down in the first person (“I ran this command on the command line.”) There’s no reason why you should get all formal and write it down in the passive voice like you typically encounter in scientific literature.

6. Use a searchable text format.

I personally use a Microsoft Word document. Some people use plain text files, or a note-taking application such as OneNote or Evernote. You can also get specialised applications devoted specifically to laboratory note-taking. LabArchives is one such example—a web-based SAAS lab notebooking platform.

While you may be tempted to record error messages or other data as screenshots, bear in mind that you will almost certainly want to search for them again in the future. Record them as text wherever possible.

For the same reason, it’s best not to use a physical notebook unless you need to do so for legal reasons. Scientists often use handwritten lab notes for patent protection purposes, but this isn’t really necessary, since there are electronic solutions that can provide a dated audit trail if needed.

7. Make your notes append-only.

You may be tempted to go back and tidy up your lab notes afterwards, but this is a temptation you need to resist. They are an audit trail, not a design document, nor a presentation, nor a manual, nor a sales pitch. Tidying them up may make them look pretty, but it undermines their integrity, and besides, it’s a waste of time.

You may want to copy and paste from your lab notes into your presentation, your design document, your wiki, or your code, but the tidying up should take place in those other documents. What you have written in your lab notes, you have written. Just move on.

8. Use your notes as a source for documentation, commit summaries and pull request descriptions.

A well maintained set of lab notes will make it much easier to compile a detailed commit summary, or a wiki page, or a pull request. Just copy and paste, and then edit to tidy up as necessary.

I frequently draft out a first version of documentation in my lab notes themselves. That way all I have to do is to copy and paste.

9. Share your notes with your whole team.

Your colleagues should all be able to refer to your notes should they need to. For example, a git bisect session may reveal that Alice was the author of a commit that introduced a bug in your payment processor on a certain date. If you can refer back to Alice’s notes on that day, you’ll have a much better idea of why she made the decisions she made, and you will be able to see how to fix the problem without breaking the new features she was working on herself.

Having said that, I’m not all that keen on the idea of having a single set of notes for the entire team. It can easily get unwieldy if everyone is working on different parts of the codebase, so it’s generally better for each individual to have their own set of notes that they write to. All in all, your mileage may vary on that one.

10. Don’t make your notes public.

If you are working on private, closed-source code, your lab notes will contain a whole lot of proprietary information. They will give your competition the heads-up about what you are working on, allowing them to beat you to market. They may also be of legal importance if your company is ever involved in a patent dispute.

Even if you are working on an open source project, there is another good reason why you should keep your lab notes private: security. They will contain a record of the exact details of any security vulnerabilities that you investigate, and any steps that you take to reproduce them. If hackers get hold of this information, you’re asking for trouble.

11. Learn from your mistakes.

If you ever find yourself asking a question about what you did last time, and your lab notes don’t answer it, that is an indication that there was some kind of information that you didn’t write down because you thought it was too trivial.

If this happens, make a note of exactly what kind of information you hadn’t written down that you should have, and write it down in future. Don’t assume that you won’t need the same kind of information again a third time. If you’ve needed it twice, the chances are pretty high that you will.

Keeping lab notes may come naturally to some programmers, while on the other hand, for others it may require considerable effort. But in the end of the day, practice makes perfect. The more you do it, and the more critically you examine your approach to it, the better you’ll get at it and the easier and more natural it will become.

SQL injection is the FizzBuzz of web security

FizzBuzz is the (in)famous interview question designed to filter out totally unqualified candidates for a programming job at a very early stage in the process. The kind who can’t solve even the very simplest programming problems and who would be wasting your time and money if you called them in for an interview after the phone screen.

You can—and should—do something similar for web security. Take a look at this snippet of Python code:

def check_password(username, password):
    db = MySQLdb.connect(passwd=DB_PASSWORD, db=DB_DATABASE)
    c = db.cursor()
    c.execute("SELECT password from tblUsers " +
        "WHERE username = \"" + username + "\"")
    row = c.fetchone()
    if row:
        return row[0] == password
    else:
        return False

Did you spot the problem? If you have any significant experience at all as a web developer, it should stand out to you like a sore thumb. You should be able to spot it in seconds, even if you have never used Python before in your life. Even if you’re the kind of .NET-only developer who insists on being spoon-fed by Microsoft and believes that Python is a dangerous heresy, it should still be glaringly obvious to you.

A couple of years ago, I used a similar question to this one on a number of interview candidates—some of them with twenty or more years of experience at a variety of impressive sounding companies. Yet it shocked me just how many of them required very heavy prompting to see it.

If you’re interviewing a candidate for a software developer role, show them this snippet of code. If they can’t tell you in seconds that it contains a SQL injection vulnerability in line 5, don’t hire them. If they can’t tell you why it’s a SQL injection vulnerability, don’t hire them. No exceptions, no excuses.

SQL injection vulnerabilities are quite frankly inexcusable. Out of all the different kinds of security vulnerabilities that you can get, they are the easiest to understand, the easiest to spot, and the easiest to avoid. Anywhere that you see user input being smashed together with any kind of instructions—SQL, SPARQL, LDAP queries, whatever—it should raise a massive red flag. A candidate who can’t spot security vulnerabilities will write security vulnerabilities (or more likely, copy and paste them from the Internet)—and if they can’t spot the simplest vulnerability of the lot, they’re going to have trouble even understanding more complex ones. And that’s before you even get started on other aspects of programming such as data integrity or performance.

With the rise of ransomware and other increasingly nasty exploits, you simply can not afford to be careless or blasé about IT security these days. As software developers, we all have a responsibility to make sure our knowledge and skills are sharp and up to date in this area, and as a recruiter, you can’t afford to take on anyone who isn’t taking this responsibility seriously.

Finally: there is a second glaring security flaw in this snippet, and candidates should be expected to spot it as well. I shall leave that one as an exercise for the reader.

Some thoughts on CQRS and Event Sourcing

CQRS and Event Sourcing have had quite a bit of a following among some developers in recent years, especially among the “passionate programmers” in the .NET ecosystem, who have been touting it as a Best Practice. They tell me that it can provide significant benefits when it’s done right, even on small projects.

This may or may not be true. The principles behind CQRS and Event Sourcing look fairly straightforward and the benefits seem clear enough. It does add some extra complexity to your architecture, but it does so in order to solve specific problems. If these are problems that the business is actually asking you to solve, and you’re taking care to keep the extra complexity under control, then you may well be doing CQRS right.

Unfortunately, I’ve more experience with projects that have got CQRS wrong than with ones that have got it right. Some of the worst examples that I’ve seen have been so bad that they made me think of Poe’s Law.

“Without a winking smiley or other blatant display of humour, it is impossible to create a parody of enterprise software best practices that someone won’t mistake for the real thing.”—Poe’s Law, Enterprise Edition™

The principles of CQRS and Event Sourcing may be straightforward enough, but the implementation is a different matter altogether. It’s very easy to end up over-complicating it, and combined with the tendency of many .NET developers to split up their solutions into far more projects and far more layers than necessary, the result can be borderline unmaintainable. I’ve seen one example that required thirty-six files to be edited in order to add a single column to a database table, and another that contained no less than thirty-nine projects in a solution consisting of a single three-page CRUD application that was only ever used by one person once a week.

One sure-fire way of doing CQRS and Event Sourcing wrong is failing to get your entire team on side with it. You may think it’s a better mental model, but the people who are going to maintain it after you need to think the same. This includes not only your domain modelling experts but also your infrastructure and DevOps guys, project managers, and anyone else who is likely to be affected by it. DevOps will want to know how you’re going to handle schema migrations, for example. HR and your project managers will want to know what skills to look for when recruiting, and how to interview for them or provide the necessary training.

I know one project that ended up being completely rewritten because the team of CQRS aficionados who built it failed to put any of this in place. They were all contractors who left without training up any of the organisation’s permanent staff in it. The result was that nobody was able to understand the codebase, let alone maintain it, and it ended up being rewritten from scratch as a conventional BOL/BLL/DAL application. The team who did so now automatically puts any CV they receive that has CQRS listed on it straight into the bin.

Another way of doing it wrong is as an exercise in CV driven development. Some people introduce CQRS and Event Sourcing into a project that they’re working on for no reason whatsoever other than to be able to list it on their CV. Don’t even think of doing this. Besides the fact that it’s stealing from the business, you’ll just end up misunderstanding it, building something that isn’t CQRS, that doesn’t solve the problems that CQRS is supposed to solve, and that over-complicates things without providing any benefit whatsoever. Ideally, you should have at least someone on your team with serious experience supporting and maintaining a legacy CQRS app in production before you try using it on greenfield work, so they can tell you what pitfalls to avoid. Like, for example, when not to use it.

I’ve no doubt that CQRS and Event Sourcing can provide significant benefits when used correctly. However, at the end of the day, any technique, tool or practice will have costs as well as benefits, whether in terms of infrastructure, training, support, maintainability, or general increased complexity. These costs need to be justified by benefits that the business is actually asking for, otherwise you will just be wasting everybody’s time and money.

Martin Fowler and feature branches revisited

Fábio asks me this by e-mail:

I found this very interesting article (http://web.archive.org/web/20110721063430/http://jamesmckay.net/2011/07/why-does-martin-fowler-not-understand-feature-branches/) that once was in your blog, and it seems it can only be accessed in the archive, or at least I was not able to find it in the live version of your blog.

Is there a reason for that? Do you still keep the same opinion? If not, can you give me a quick hint of what to read to reach the same conclusion?

In answer to his question, I took the original blog post down in January 2013 along with everything else on my blog, because I wanted to give it a complete reboot. In the years since then, I’ve restored some of them going as far back as 2009,  but I hadn’t restored that particular post, mainly because I felt that I’d been too confrontational with it and it hadn’t made me look good. However, since it’s out there in archive.org, and people are still asking about it, I’ve now restored it for historical reference. Unfortunately, I haven’t restored the comments because I no longer have a backup of them.

A bit of historical background.

I wrote the original post in July 2011. At the time, distributed version control tools such as Git and Mercurial had been around for about six years, but were still very new and unfamiliar to most developers. Most enterprise organisations were deeply entrenched in old-school tools such as Subversion and Team Foundation Server, which made branching and merging much harder and much more confusing than necessary, most corporate developers were terrified of the concept, and vendors of these old-school tools were playing on this fear for all it was worth. This was intensely frustrating to those of us who had actually used Git and Mercurial, could clearly see the benefits, and yet were being stonewalled by 5:01 dark matter colleagues and managers who didn’t want to know. To us, Subversion was The Enemy, and to see someone of Martin Fowler’s stature apparently siding with the enemy was maddening.

On the other hand, these tools weren’t yet quite enterprise ready, with only weak Windows support and rudimentary GUIs. SourceTree was not yet a thing. Furthermore, the best practices surrounding them were still being thrashed out and debated by early adopters in the blogosphere and at conferences. In a sense, nobody properly understood feature branches yet. If you read all the discussions and debates at the time, we didn’t even agree about exactly what feature branches were. Martin Fowler, Jez Humble and others were working with the assumption that they referred to branches lasting several days or even weeks, while people such as Adam Dymitruk and myself went by a much broader definition that basically amounted to what we would call a pull request today, albeit with the proviso that they should be kept as short as possible.

These days, of course, everybody (or at least, everybody who’s worth working for) uses Git, so that particular question is moot, and we can now freely discuss best practices around branching and merging as mature adults.

The state of the question in 2017.

I’m generally somewhat more sympathetic to Martin Fowler’s position now than I was six years ago. Most of his concerns about feature branches are valid ones. Long-lived feature branches can be difficult to work with, especially for inexperienced teams and badly architected codebases, where big bang merges can be a significant problem. Feature branches can also be problematic for Continuous Integration and opportunistic refactoring, so they should very much be the exception rather than the rule. Feature toggles can also provide considerable benefits. You can use them for A/B testing, country-specific features, premium features for paying customers, and so on and so forth. I even started writing my own .NET-based web framework built around feature toggles, though as I’m no longer working with .NET, it’s not being actively developed.

However, many of my original points still stand. Short-lived branches, such as pull requests, are fine, and should in fact be the default, because code should be reviewed before it is integrated, not after the fact. Furthermore, if you’re using feature toggles solely as a substitute for branching and merging, you are releasing code into production that you know for a fact to be immature, untested, buggy, unstable and not fit for purpose. Your feature toggles are supposed to isolate this code of course, but there is always a risk that the isolation could be incomplete, or that the toggle could be flipped prematurely by mistake. When feature branches go wrong, they only go wrong in your development environment, and the damage is relatively limited. When feature toggles go wrong, on the other hand, they go wrong in production—sometimes with catastrophic results.

Just how catastrophic? The feature toggles article on Martin Fowler’s own website itself cites an example where badly implemented feature toggles cost one company $460 million in just 45 minutes. The company concerned, we are told, “went from being the largest trader in US equities and a major market maker in the NYSE and NASDAQ to bankrupt.” To be fair, there were other problems—they relied extensively on manual deployment processes, for example—but it is still a cautionary tale for anyone who thinks feature toggles should always be viewed as a Best Practice without exception.

Of course, not all feature toggles carry this level of risk, and in many cases, the effects of inadvertent exposure will be mostly harmless. In these cases, feature toggles will indeed be the better option, not least because they’re easier to work with. But in general, when deciding whether to use a feature branch or a feature toggle, always ask yourself the question: what would be the damage that this feature would cause if it were activated prematurely? If it’s not a risk you’re prepared to take, your code is better off on a separate branch.