I’ve recently had the opportunity to start a Specflow/Selenium end to end testing project from scratch and my gosh it’s been fun. I’m one of those people that absolutely love unit tests and trying to “trick” the code with complicated scenarios. End to end testing with Selenium is like that but on steroids. Seeing the browser flash infront of you and motor through tests is an amazing feeling.

But in saying that. A key part of using Selenium is the “ChromeWebDriver”. It’s the tool that actually allows you to manipulate the Google Chrome browser through selenium. And let me tell you, there are a few headaches getting this set up that I really didn’t expect. Version errors, Not finding the right exe, Nuget packages that actually include the exe but it’s the wrong version or can’t be found. Ugh.

If you are not that big into automation testing, you can probably skip this whole post. But if you use Specflow/Selenium even semi-regularly, I highly recommend bookmarking this post because I’m 99% sure you will hit atleast one of these bugs when setting up a new testing project.

Chrome, Gecko  and IE Drivers

While the below is mostly about using ChromeDriver, some of this is also applicable for Gecko (Firefox), and IE drivers. Obviously the error messages will be slightly different, but it’s also highly likely you will run into very similar issues.

Adding ChromeDriver.exe To Your Project

The first thing to note is that you’ve probably added the “Selenium.WebDriver” and maybe “Specflow” nuget packages. These however *do not* contain the actual ChromeDriver executable. They only contain the C# code required to interact with the driver, but *not* the driver itself. It is incredibly confusing at first but kinda makes sense because you may want to only use Chrome or only Firefox or a combination etc. So it’s left up to you to actually add the required driver EXEs.

If you try and run your selenium tests without it, it will actually compile all fine and look like starting only to bomb out with :

Depending on your setup, it can also bomb out with :

So there are two ways to add ChromeDriver to your project. The first is that you can install a nuget package that will write it to your bin folder when building. The most common nuget package that does this is here : https://www.nuget.org/packages/Selenium.WebDriver.ChromeDriver/

But a quick note, as we will see below, this only works if everywhere you run the tests has the correct version of chrome that matches the driver. What?! You didn’t know that? That’s right. The version of ChromeDriver.exe will have a version like that will typically only be able to run on machines that have chrome version 79 installed. The nuget package itself is typically marked with the version of Chrome you need, so it’s easy to figure out, but can still be a big pain in the butt to get going.

So with that in mind, the other option is to actually download the driver yourself from the chromium downloads page : https://chromedriver.chromium.org/downloads

You need to then drop the exe into your project. And make sure it’s set to copy if newer for your build. Then when building, it should show up in your bin folder. Personally, I found the manual download of the chromium driver to be handy when working in an enterprise environment where the version of chrome might be locked down by some group policy, or you are working with others who may have wildly different versions of chrome and you can do funky things like have different versions for different developers.

Passing The ChromeDriver Location

So you’ve downloaded ChromeDriver and when you build, you can see it in your bin folder, but everything is still blowing up with the same error, what gives?!

One of the more irritating things I found is that in so many tutorials, they new’d up a chromedriver instance like so :

Now this may have worked in .NET Framework (I haven’t tried), but atleast for me in .NET Core, this never works. I think there must be something inside the constructor of ChromeDriver that looks up where it’s current executable is running (e.g. where the Bin folder is), and in .NET Core this must be different from Full Framework.

In anycase, you can change the constructor to instead take the folder location where it can find the driver. In my case I want that to be the bin folder :

Obviously you can go ahead and change the path to anything which is super handy for differing dev setups. For example you could ask each dev to maintain their own version of chromedriver.exe somewhere on their C:\ drive, and then just pass that location into the constructor. Meaning that each developer can have a completely different version of chrome, and things will still run perfectly fine.

Versions Matter

We kinda touched on it above, but versions of ChromeDriver have to match the actual version of Chrome on the machine. If you are getting errors like so :

Then you have a mismatch between versions.

The easiest way to rectify the issue is to manually download the correct version of ChromeDriver from here : https://chromedriver.chromium.org/downloads and force your code to use it. If you are using a nuget package for the driver, then it’s highly likely you would need to switch away from it to a manual setup to give you better control over versioning.

Azure Devops (And Others) Have ChromeDriver Environment Variables

This is one that I really wish I knew about sooner. When I tried to run my Selenium tests on Azure Devops, I was getting version issues where the version of Chrome on my hosted build agent was just slightly different from the one on my machine. I tried to do all sorts of crazy things by swapping our the exe version etc, but then I found buried in a help doc that there is actually an environment variable named ChromeWebDriver that has the full path to a chromedriver that is guaranteed to match that of the chrome browser on the agent. So I wrote some quick code that if I was running inside Azure Devops, to grab that environment variable and pass that into my ChromeDriver constructor.

Again, this is only for Azure Devops. But if you are using Gitlab, Bamboo, TeamCity, whatever! Check to see if there is an environment variable on hosted agents that carries the location of ChromeDriver.

If you are using your own build agents, then it’s also a good idea to think about following the same pattern. It’s super handy to have the Build Agent look after it’s own versions rather than wrangling something in code to fudge it all.

Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

Opening Excel files in code has been a painful experience long before .NET Core came along. In many cases, you actually needed the Excel application installed on the target/users machine to be able to open excel files via code. If you’ve ever had to use those “OLE DB Jet ” queries before, you know it’s not a great experience. Luckily there are some pretty good open source solutions now that don’t require excel on the target machine. This is good for Windows users so that you don’t have to install excel on a target users machine or web server, but also for people hosting .NET Core applications on Linux (And even Mac/ARM) – where Excel is obviously no where to be seen!

My methodology for this article is pretty simple. Create a standardized excel workbook with a couple of sheets, couple of formulas, and a couple of special formatting cases. Read the same data out in every single library and see which one works the best for me. Simple! Let’s get going!

Note On CSV Formats

I should note that if you are reading a CSV, or more so a single excel sheet that doesn’t have formulas or anything “excel” specific on the sheet, you should instead just parse it using standard CSV technique. We have a great article here on parsing CSV in .NET Core that you should instead follow. CSV parsers are great for taking tabular data and deserializing it into objects and should be used where they can.

Example Data

I figure the best way to compare the different libraries on offer is to create a simple spreadsheet to compare the different ways we can read data out. The spreadsheet will have two “sheets”, where the second sheet references the first.

Sheet 1 is named “First Sheet” and looks like so :

Notice that cell A2 is simply the number “1”. Then in column B2, we have a reference to cell A2. This is because we want to check if the libraries allow us to not only get the “formula” from the cell, but also what the computed value should be.

We are also styling cell A2 with a font color of red, and B2 has a full border (Although hard to see as I’m trying to show the fomula). We will try and extract these styling elements out later.

Sheet 2 is named “Second Sheet” and looks like so :

So we are doing a simple “SUM” formula and referencing the first sheet. Again, this is so we can test getting both the formula and the computed value, but this time across different sheets. It’s not complicated for a person used to working with Excel, but let’s see how a few libraries handle it.

In general, in my tests I’m looking for my output to always follow the same format of :

That way when I show the code, you can pick the library that makes the most sense to you.


When I first started hunting around for parsing excel in .NET Core, I remembered using EPPlus many moons ago for some very lightweight excel parsing. The nuget package can be found here : https://www.nuget.org/packages/EPPlus/. It’s also open source so you can read through the source code if that’s your thing here : https://github.com/JanKallman/EPPlus

The code to read our excel spreadsheet looks like so :

Honestly what can I say. This was *super* easy and worked right out of the box. It picks up formulas vs text perfectly! The styles on our first sheet was also pretty easy to get going. The border is slightly annoying because you have to check the “Style” of the border, and if it’s a style of “None”, then it means there is no border (As opposed to a boolean for “HasBorder” or similar). But I think I’m just nit picking, EPPlus just works!


NPOI is another open source option with a Github here : https://github.com/tonyqus/npoi and Nuget here : https://www.nuget.org/packages/NPOI/. It hasn’t had a release in over a year which isn’t that bad because it’s not like Excel itself has tonnes of updates throughout the year, but the Issues list on Github is growing a bit with a fair few bugs so keep that in mind.

The code to read our data using NPOI looks like so :


…Actually you know what. I blew a bunch of time on this to try and work out the best way to use NPOI and the documentation is awful. The wiki is here : https://github.com/tonyqus/npoi/wiki/Getting-Started-with-NPOI but it has a few samples but most/all of them are about creating excel workbooks not reading them. I saw they had a link to a tutorial on how to read an Excel file which looked promising, but it was literally reading the spreadsheet and then dumping the text out.

After using EPPlus, I just didn’t see any reason to continue with this one. Almost every google answer will lead you to StackOverflow with people using NPOI with such specific use cases that it never really all pieced together for me.


ExcelDataReader appeared in a couple of stackoverflow answers on reading excel in .NET Core. Similar to others in this list, it’s open source here : https://github.com/ExcelDataReader/ExcelDataReader and on Nuget here : https://www.nuget.org/packages/ExcelDataReader/

I wanted to make this work but…. It just doesn’t seem intuitive at all. ExcelDataReader works on the premise that you are reading “rows” and “columns” sequentially in almost a CSV fashion. That sort of works but if you are looking for a particular cell, it’s rough as hell.

Some example code :

The first line in particular is really annoying (Everything blows up without it). But you’ll notice that we are moving through row by row (And sheet by sheet) trying to get values. Ontop of that, calling things like “GetString” doesn’t work if the value is a decimal (Implicit casts would have been better IMO). I also couldn’t find any way to get the actual formula of the cell. The above only returns the computed results.

I was going to slog my way through and actually get the result we were looking for, but it’s just not a library I would use.


Syncfusion is one of those annoying companies that create pay-to-use libraries, upload them to nuget, and then in small print  say you need to purchase a license or else. Personally, I would like to see Microsoft not allow paid libraries into the public Nuget repo. I’m going to include them here but their licensing starts at $995 per year, per developer, so I don’t see much reason to use it for the majority of use cases. The nuget page can be found here https://www.nuget.org/packages/Syncfusion.XlsIO.Net.Core/

The code looks like :

So not bad. I have to admit, I fiddled around trying to understand how it worked out borders (As the above code doesn’t work), but gave up. The font color also took some fiddling where the library returns non standard objects as the color. Some of the properties for the actual data are also a bit confusing where you have value, text, displaytext etc. All returning slightly different things so you sort of have to just spray and pray and see which one works.

If EPPlus didn’t exist, and Syncfusion wasn’t fantastically overpriced, this library would actually be pretty good.


Use EPPlus. https://github.com/JanKallman/EPPlus


Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

This article is part of a series on creating Windows Services in .NET Core.

Part 1 – The “Microsoft” Way
Part 2 – The “Topshelf” Way
Part 3 – The “.NET Core Worker” Way

This article has been a long time coming I know. I first wrote about creating Windows Services in .NET Core all the way back in September (3 months ago). And on that post a helpful reader (Shout out to Saeid!) immediately commented that in .NET Core 3, there is a brand new way to create Windows Services! Doh! It reminds me of the time I did my 5 part series on Azure Webjobs in .NET Core, and right as I was completing the final article, a new version of the SDK got released with a tonne of breaking changes making me have to rewrite a bunch.

Thankfully, this isn’t necessarily a “breaking change” to how you create Windows Services, the previous articles on doing it the “Microsoft Way” and the “Topshelf Way” are still valid, but this is just another way to get the same result (Maybe with a little less cursing to the programming gods).

The Setup

The first thing you need to know is that you need .NET Core 3.0 installed. At the time of writing, .NET Core 3.1 has just shipped and Visual Studio should be prompting you to update anyway. But if you are trying to do this in a .NET Core 2.X project, it’s not going to work.

If you like creating projects from the command line, you need to create a new project as the type “worker” :

If you are a Visual Studio person like me, then there is actually a template inside Visual Studio that does the exact same thing.

Doing this creates a project with essentially two files. You will have your program.cs which is basically the “bootstrapper” for your app. And then you have something called worker.cs which is where the logic for your service goes.

It should be fairly easy to spot, but to add extra background services to this program to run in parallel, you just need to create a new class that inherits from BackgroundService :

Then in our program.cs file, we just add the worker to our service collection :

AddHostedService has actually been in the framework for quite some time as a “background service” type task runner that typically runs underneath your web application. We’ve actually done an article on hosted services in ASP.NET Core before, but in this case, the hosted service is basically the entire app rather than it being something that runs behind the scenes of your web app.

Running/Debugging Our Application

Out of the box, the worker template has a background service that just pumps out the datetime to the the console window. Let’s just press F5 on a brand new app and see what we get.

We are up and running immediately! We can leave our console window open to debug the application, or close the window to exit. Compared to the hell we went through trying to debug our Windows Service when creating it the “Microsoft” way, this is like heaven.

Another thing to note is that really what we have infront of us is a platform for writing console applications. In the end we are only writing out the time to the console window, but we are also doing that via Dependency Injection creating a hosted worker. We can use this DI container to also inject in repositories, set environments, read configuration etc.

The one thing it’s not yet is a windows service…

Turning Our App Into A Windows Service

We need to add the following package to our app :

Next, head to our program.cs file and modify it by adding a call to “UseWindowsService()”.

And that’s it!

Running our application normally is just the same and everything functions as it was. The big difference is that we can now install everything as a service.

To do that, first we need to publish our application. In the project directory we run :

Note in my case, I’m publishing for Windows X64 which generally is going to be the case when deploying a Windows service.

Then all we need to do is run the standard Windows Service installer. This isn’t .NET Core specific but is instead part of Windows :

As always, the other commands available to you (including starting your service) are :

And checking our services panel :

It worked!

Installing On Linux

To be honest, I don’t have a hell of a lot of experience with Linux. But the general gist is…

Instead of installing Microsoft.Extensions.Hosting.WindowsServices , you need to install Microsoft.Extensions.Hosting.Systemd . And then instead of calling UseWindowsService()  you’ll instead call UseSystemd() .

Obviously your dotnet publish and installation commands will vary, but more or less you can create a “Windows Service” that will also run on Linux!

Microsoft vs Topshelf vs .NET Core Workers

So we’ve now gone over 3 different ways to create Windows Services. You’re probably sitting there going “Well… Which one should I chose?”. Immediately, let’s bin the first Microsoft old school way of going things. It’s hellacious to debug and really doesn’t have anything going for it.

That leaves us with Topshelf and .NET Core workers. In my opinion, I like .NET Core Workers for fitting effortlessly into the .NET Core ecosystem. If you’re already developing in ASP.NET Core, then everything just makes sense creating a worker. On top of that, when you create a BackgroundService, you can actually lift and shift that to run inside an ASP.NET Core website at any point which is super handy. The one downside is the installation. Having to use SC commands can be incredibly frustrating at times and Topshelf definitely has it beat there.

Topshelf in general is very user friendly and has the best installation process for Windows Services. But it’s also another library to add to your list and another “framework” to learn, which counts against it.

Topshelf or .NET Core Workers, take your pick really.

Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

These days, people who are considered “fullstack” developers are considered to be unicorns. That is, it’s seemingly rare for new grad developers to be fullstack, and instead they are picking a development path and sticking with it. It wasn’t really like that 10-15 years ago. When I first started developing commercially I obviously got to learning ASP.NET (Around .NET 2-ish), but you better believe I had to learn HTML/CSS and the javascript “framework” of the day – jQuery. There was no “fullstack” or “front end” developers, you were just a “developer”.

Lately my javascript framework of choice has been Angular. I started with AngularJS 1.6 and took a bit of a break, but in the last couple of years I’ve been working with Angular all the way up to Angular 8. Even though Angular’s documentation is actually pretty good, there’s definitely been a few times where I feel I’ve cracked a chestnut of a problem and thought “I should really start an Angular blog to share this”. After all, that’s exactly how this blog started. In the dark days of .NET Core (before the first release even!), I was blogging here trying to help people running into the same issues as me.

And so, I’ve started Tutorials For Angular. I’m not going to profess to be a pro in Angular (Or even javascript), but I’ll be sharing various tips and tricks that I’ve run into in my front end development journey. Content is a bit light at the moment but I have a few long form articles in the pipeline on some really tricky stuff that stumped me when I got back into the Angular groove, so if that sounds like you, come on over and join in!

Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

Rate limiting web services and APIs is nothing new, but I would say over the past couple of years the “leaky bucket” strategy of rate limiting has rised in popularity to the point where it’s almost a defacto these days. The leaky bucket strategy is actually quite simple – made even easier by the fact that it’s name comes from a very physical and real world scenario.

What Is A Leaky Bucket Rate Limit?

Imagine a 4 litre physical bucket that has a hole in it. The hole leaks out 1 litre of water every minute. Now you can dump 4 litres of water in the bucket all at once just fine, but still it will flow out at 1 litre per minute until it’s empty. If you did fill it immediately, after 1 minute, you could make 1 request but then have to wait another minute. Or you could wait 2 minutes and make 2 at once etc.  The general idea behind using a leaky bucket scenario over something like “1 call per second” is that it allows you to “burst” through calls until the bucket is full, and then wait a period of time until the bucket drains. However even while the bucket is draining you can trickle in calls if required.

I generally see it applied on API’s that to complete a full operation may take 2 or 3 API calls, so limiting to 1 per second is pointless. But allowing a caller to burst through enough calls to complete their operation, then back off, is maybe a bit more realistic.

Implementing The Client

This article is going to talk about a leaky bucket “client”. So I’m the one calling a web service that has a leaky bucket rate limitation in place. In a subsequent article we will look at how we implement this on the server end.

Now I’m the first to admit, this is unlikely to win any awards and I typically shoot myself in the foot with threadsafe coding, but here’s my attempt at a leaky bucket client that for my purposes worked a treat, but it was just for a small personal project so your mileage may vary.

There is a bit to unpack there but I’ll do my best.

  • We have a class called BucketConfiguration which specifies how full the bucket can get, and how much it leaks.
  • Our main method is called “GainAccess” and this will be called each time we want to send a request.
  • We use a SemaphoreSlim just incase this is used in a threaded scenario so that we queue up calls and not get tangled up in our own mess
  • On the first call to gain access, we kick off a thread that is used to “empty” the bucket as we go.
  • Then we enter in a loop. If the current items on the queue is the max fill, then we just wait a second and try again.
  • When there is room on the queue, we pop our time on and return, thus gaining access.

Now I’ve used a queue here but you really don’t need to, it’s just helpful debugging which calls we are leaking etc. But really a blockingcollection or something similar is just as fine. Notice that we also kick off a thread to do our leaking. Because it’s done at a constant rate, we need a dedicated thread to be “dripping” out requests.

And finally, everything is async including our semaphore (If you are wondering why I didn’t just use the *lock* keyword, it can’t be used with async code). This means that we hopefully don’t jam up threads waiting to send requests. It’s not foolproof of course, but it’s better than hogging threads when we are essentially spinwaiting.

The Client In Action

I wrote a quick console application to show things in action. So for example :

Running this we get :

Makes sense. We do our run of 4 calls immediately, but then we have to back off to doing just 1 call every 5 seconds.

That’s pretty simple, but we can also handle complex scenarios such as leaking 2 requests instead of 1 every 5 seconds. We change our leaky bucket to :

And what do you know! We see our burst of 4 calls, then every 5 seconds we see us drop in another 2 at once.


Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

This article is part of a series on the SOLID design principles. You can start here or jump around using the links below!

S – Single Responsibility
O – Open/Closed Principle
L – Liskov Substitution Principle
I – Interface Segregation Principle
D – Dependency Inversion

OK, let’s just get the Wikipedia definitions out of the way to begin with :

  1. High-level modules should not depend on low-level modules. Both should depend on abstractions (e.g. interfaces).
  2. Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.

While this may sound complicated, it’s actually much easier when you are working in the code. Infact it’s probably something you already do in (Especially in .NET Core) but you don’t even think about.

In simple terms, imagine we have a service that calls into a “repository”. Generally speaking, that repository would have an interface and (especially in .NET Core) we would use dependency injection to inject that repository into the service, however the service is still working off the interface (an abstraction), instead of the concrete implementation. On top of this, the service itself doesn’t know anything about how the repository actually gets the data. The repository could be calling a SQL Server, Azure Table Storage, a file on disk etc – but to the service, it really doesn’t matter. It just knows that it can depend on the abstraction to get the data it needs and now worry about any dependencies the repository may have.

Dependency Inversion vs Dependency Injection

Very commonly, people mix up dependency injection and dependency inversion. I know many years ago in an interview I was asked in an interview to list out SOLID and I said Dependency Injection as the “D”.

Broadly speaking, Dependency Injection is a way to achieve Dependency Inversion. Like a tool to achieve the principle. While Dependency Inversion is simply stating that you should depend on abstractions, and that higher level modules should not worry about dependencies of the lower level modules, Dependency Injection is a way to achieve that by being able to inject dependencies.

Another way to think about it would be that you could achieve Dependency Inversion by simply making liberal use of the Factory Pattern to create lower level modules (Thus abstracting away any dependencies they have), and have them return interfaces (Thus the higher level module depends on abstractions and doesn’t even know what the concrete class behind the interface is).

Even using a Service Locator pattern – which arguably some might say is dependency injection, could be classed as dependency inversion because you aren’t worrying about how the lower level modules are created, you just call this service locator thingie and magically you get a nice abstraction.

Dependency Inversion In Practice

Let’s take a look at an example that doesn’t really exhibit good Dependency Inversion behaviour.

The problem with this code is that MyService very heavily relies on concrete implementation details of the PersonRepository. For example it’s required to pass it a connection string (So we are leaking out that it’s a SQL Server), and a connection timeout. The PersonRepository itself allows a “ConnectToDatabase” method which by itself is not terribly bad, but if it’s required to call “ConnectToDatabase” before we can actually call the “GetAllPeople” method, then again we haven’t managed to abstract away the implementation detail of this specifically being a SQL Server repository.

So let’s do some simple things to clean it up :

Very simple. I’ve created an interface called IPersonRepository that shields away implementation details. I’ve taken that repository and (not shown) used dependency injection to inject it into my service. This way my service doesn’t need to worry about connection strings or other constructor requirements. I also removed the “ConnectToDatabase” method from being public, the reason being my service shouldn’t worry about pre-requisites to get data. All it needs to know is that it calls “GetAllPeople” and it gets people.

Switching To A Factory Pattern

While writing this post, I realized that saying “Yeah so I use this magic thing called Dependency Injection” and it works isn’t that helpful. So let’s quickly write up a factory instead.

Obviously not as nice as using Dependency Injection, and there are a few different ways to cut this, but the main points of dependency inversion are still there. Notice that still, our service does not have to worry about implementation details like connection strings and it still depends on the interface abstraction.

What’s Next

That’s it! You’ve made it to the end of the series on SOLID principles in C#/.NET. Now go out and nail that job interview!

Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

This article is part of a series on the SOLID design principles. You can start here or jump around using the links below!

S – Single Responsibility
O – Open/Closed Principle
L – Liskov Substitution Principle
I – Interface Segregation Principle
D – Dependency Inversion

The interface segregation principle can be a bit subjective at times, but the most common definition you will find out there is :

 No client should be forced to depend on methods it does not use

In simple terms, if you implement an interface in C# and have to throw NotImplementedExceptions you are probably doing something wrong.

While the above is the “definition”, what you will generally see this principle described as is “create multiple smaller interfaces instead of one large interface”. This is still correct, but that’s more of a means to achieve Interface Segregation rather than the principle itself.

Interface Segregation Principle In Practice

Let’s look at an example. If we can imagine that I have an interface called IRepository, and from this we are reading and writing from a database. For some data however, we are reading from a local XML file. This file is uneditable and so we can’t write to it (essentially readonly).

We still want to share an interface however because at some point we will move the data in the XML file to a database table, so it would be great if at that point we could just swap the XML repository for a database repository.

Our code is going to look a bit like this :

Makes sense. But as we can see for our XMLFileRepository, because we don’t allow writing, we have to throw an exception (An alternative would to just have an empty method which is probably even worse). Clearly we are violating the Interface Segregation Principle because we are implementing an interface whose methods we don’t actually implement. How could we implement this more efficiently?

In this example we have moved the reading portion of a repository to it’s own interface, and let the IRepository interface inherit from it. This means that any IRepository can also be cast and made into an IReadOnlyRepository. So if we swap out the XmlFileRepository for a DatabaseRepository, everything will run as per normal.

We can even inject in the DatabaseRepository into classes that are looking for IReadOnlyRepository. Very nice!

Avoiding Inheritance Traps

Some people prefer to not use interface inheritance as this can get messy fast, and instead have your concrete class implement multiple smaller interfaces :

This means you don’t get tangled up with a long line of inheritance, but it does have issues when you have a caller that wants to both read *and* write :

Ultimately it’s up to you but it’s just important to remember that these are just a means to an end. As long as a class is not forced to implement a method it doesn’t care about, then you are abiding by the Interface Segregation Principle.

What’s Next

Next is our final article in this series, the D in SOLID. Dependency Inversion.

Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

This article is part of a series on the SOLID design principles. You can start here or jump around using the links below!

S – Single Responsibility
O – Open/Closed Principle
L – Liskov Substitution Principle
I – Interface Segregation Principle
D – Dependency Inversion

What Is The Liskov Principle?

The Liskov Principle has a simple definition, but a hard explanation. First, the definition :

Types can be replaced by their subtypes without altering the desirable properties of the program.

So basically if I have something like this :

If in the future I decide that MyService should depend on MySubType instead of MyType, theoretically I shouldn’t alter “the desirable properties of the program”. I put that in quotes because what does that actually mean? A large part of inheritance is extending functionality and therefore by definition it will alter the behaviour of the program in some way.

That last part might be controversial because I’ve seen plenty of examples of Liskov that state that overriding a method in a sub class (which is pretty common) to be a violation of the principle but I feel like in reality, that’s just going to happen and isn’t a design flaw. For example :

Is this a violation? It could be because substituting the subtype may not “break” functionality, but it certainly changes how the program functions and could lead to unintended consequences. Some would argue that Liskov is all about behavioural traits, which we will look at later, but for now let’s look at some “hard” breaks. e.g. Things that are black and white wrong.

Liskov On Method Signatures

The thing is, C# is actually very hard to violate Liskov and that’s why you might find that examples out there are very contrived. Indeed, for the black and white rules that we will talk about below, you’ll notice that they are things that you really need to go out of your way (e.g. ignore compiler warnings) to break. (And don’t worry, I’ll show you how!).

Our black and white rules that no one will argue with you on Stackoverflow about are….

A method of a subclass can accept a parent type as a parameter (Contravariance)

The “idea” of this is that a subclass can override a method and accept a more general parameter, but not the opposite. So for example in theory Liskov allows for something like this :

But actually if you try this, it will blow up because in C# when overriding a method the method signature must be exactly the same. Infact if we remove the override keyword it just acts as a method overload and both would be available to someone calling the MySubType class.

A method of a subclass can return a sub type as a parameter (Covariance)

So almost the opposite of the above, when we return a type from a method in a subclass, Liskov allows it to be “more” specific than the original return type. So again, theoretically this should be OK :

This actually compiles but we do get a warning :

Yikes. We can get rid of this error message by following the instruction and changing our SubType to the following :

Pretty nasty. I can honestly say in over a decade of using C#, I have never used the new  keyword to override a method like this. Never. And I feel like if you are having to do this, you should stop and think if there is another way to do it.

But the obvious issue now is that anything that was expecting an object back is now getting this weird “MyReturnType” back. Exceptions galore will soon follow. This is why it makes it to a hard rule because it’s highly likely your code will not compile doing this.

Liskov On Method Behaviours

Let’s jump into the murky waters on how changing the behaviour of a method might violate Liskov. As mentioned earlier, I find this a hard sell because the intention of overriding a method in C#, when the original is marked as virtual, is that you want to change it’s behaviour. It’s not that C# has been designed as an infallible language, but there are pros to inheritance.

Our behavioural rules are :

Eceptions that would not be thrown normally in the parent type can’t then be thrown in the sub type

To me this depends on your coding style but does make sense in some ways. Consider the following code :

If you have been using the original type for some time, and you are following the “Gotta catch ’em all” strategy of exceptions and trying to catch each and every exception, then you may be intending to catch the ArgumentException. But now when you switch to the subtype, it’s throwing a NullReferenceException which you weren’t expecting.

Makes sense, but the reality is that if you are overriding a method to change the behaviour in some way it’s an almost certainty that new exceptions will occur. I’m not particularly big on this rule, but I can see why it exists.

Pre-Conditions cannot be strengthened and Post-Conditions cannot be weakened in the sub type

Let’s look at pre-conditions first. The idea behind this is that if you were previously able to call a method with a particular input parameter, new “rules” should not be in place that now rejects those parameters. A trivial example might be :

Where previously there was no restriction on null values, there now is.

Conversely, we shouldn’t weaken the ruleset for returning objects. For example :

We could previously rely on the return object never being null, but now we may be returned a null object.

Similar to the exceptions rule, it makes sense that when extending behaviour we might have no choice but to change how we handle inputs and outputs. But unlike the exceptions rule, I really like this rule and try and abide by it.

Limiting General Behaviour Changes

I just want to quickly show another example that possibly violates the Liskov principle, but is up to interpretation. Take a look at the following code :

A somewhat trivial example but if someone is depending on the class of “Jar” and calling Pour, everything is going fine. But if they then switch to using JarWithLid, their code will no longer function as intended because they are required to open the Jar first.

In some ways, this is covered by the “pre-Conditions cannot be strengthened” rule. It’s clearly adding a pre-existing condition that the jar must be opened before it can be poured. But on the other hand, in a more complex example a method may be hundreds of lines of code and have various new behaviours that affect how the caller might interact with the object. We might classify some of them as “pre-conditions” but we may also just classify them as behavioural changes that are inline with typical inheritance scenarios.

Overall, I feel like Liskov principle should be about limiting “breaking” changes when swapping types for subtypes, whether that “breaking” change is an outright compiler error, logic issue, or unexpected behavioural change.

What’s Next?

Up next is the I in SOLID. That is, The Interface Segregation Principle.

Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

This article is part of a series on the SOLID design principles. You can start here or jump around using the links below!

S – Single Responsibility
O – Open/Closed Principle
L – Liskov Substitution Principle
I – Interface Segregation Principle
D – Dependency Inversion

What Is The Open/Closed Principle?

Like our post on Single Responsibility, let’s start off with the Wikipedia definition of the Open/Closed Principle :

Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification

Probably not that helpful to be honest. It’s sort of an open ended statement that could be taken to mean different things for different developers.

In looking at resources for this article, I actually found many write ups talking about how being able to substitute one implementation of an interface for another was an example of being Open/Closed, and indeed Wikipedia touches on this :

During the 1990s, the open/closed principle became popularly redefined to refer to the use of abstracted interfaces, where the implementations can be changed and multiple implementations could be created and polymorphically substituted for each other.

I’m not the right person to start redefining decades of research into software design, but I personally don’t like this definition as I feel like it very closely resembles the Liskov Principle (Which we will talk about in our next article in this series). Instead I’ll describe it more loosely as :

Can I extend this code and add more functionality without modifying the original code in any way.

I’m going to take this explanation and run with it.

Open/Closed Principle In Practice

Let’s take our code example that we finished with from the Single Responsibility article. It ended up looking like this :

Looks OK. But what happens if we want to also check other usernames and reject the registration if they fail? We might end up with a statement like so :

Is this just continue on forever? Each time we are actually modifying the logic of our app and we are probably going to have to regression test that past use cases are still valid every time we edit this method.

So is there a way to refactor this class so that we are able to add functionality (Add blacklisted usernames for example), but not have to modify the logic every time?

How about this! We create an interface that provides a list of Blacklisted Usernames :

Then we inject this into our RegisterService class and modify our register method to simply check against this list.

Better right? Not only have we removed having hardcoded strings in our code (which is obviously beneficial), but now when we extend that list out of usernames we don’t want to allow, our code actually doesn’t change at all.

This is the Open/Closed Principle.

Extending Our Example

The thing is, we’ve taken a list of hardcoded strings and made them be more configuration driven. I mean yeah, we are demonstrating the principle correctly, but we are probably also just demonstrating that we aren’t a junior developer. Let’s try and take our example that one step further to make it a bit more “real world”.

What if instead of just checking against a blacklisted set of usernames, we have a set of “pre-registration checks”. These could grow over time and we don’t want to have a huge if/else statement littered through our method. For example changing our code to look like this would be a bad idea :

How many statements are we going to add like this? And each time we are subtly changing the logic for this method that requires even more regression testing.

How about this instead, let’s create an interface for registration pre checks and implement it like so :

Now we can modify our RegisterService class to instead take a list of pre checks and simply check all of them in our RegisterUser method :

Now if we add another pre-check, instead of changing the logic of our RegisterUser method, we just add it to the list of pre-checks passed into the constructor and there is no modification necessary. This is probably a better example of the Open/Closed Principle that demonstrates the ability to add functionality to a class that doesn’t require changes to the existing logic.

What’s Next?

Up next is the L in SOLID. That is, The Liskov Principle.

Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

This article is part of a series on the SOLID design principles. You can start here or jump around using the links below!

S – Single Responsibility
O – Open/Closed Principle
L – Liskov Substitution Principle
I – Interface Segregation Principle
D – Dependency Inversion

What Is SOLID?

SOLID is a set of 5 design principles in software engineering intended to make software development more flexible, easier to maintain, and easier to understand. While sometimes seen as a “read up on this before my job interview” type of topic, SOLID actually has some great fundamentals for software design that I think is applicable at all levels. For example, I commonly tell my Intermediate developers that when doing a code review, don’t think about “How would I implement this?” but instead “Does this follow SOLID principles?”. Not that things are ever as black and white as that, but it forms a good starting point for looking at software design objectively.

Like all “patterns” and “principle” type articles. Nothing should be taken as being “do this or else”, but hopefully throughout this series we can take a look at the SOLID principles at a high level, and you can then take that and see how it might apply to your day to day programming life. First up is the “Single Responsibility Principle”.

What Is Single Responsibility?

I remember reading a definition of Single Responsibility as being :

A class should have only one reason to change

And all I could think was… And what is that reason? Was the quote cut off? Was there more to this?

And I don’t think I’m alone. I feel like this definition is a somewhat backwards way of saying what we probably all intuitively think of when we see “Single Responsibility”. But once we explore the full picture, it’s actually quite a succinct way of describing the principle. Let’s dive right in.

Single Responsibility In Practice

If we can, let’s ignore the above definition for a moment and look at how the single responsibility principle would actually work in practice.

Say I have a class that registers a new user on my website. The service might look a bit like so :

Pretty simple :

  • Check to see if the user is an admin, if it is throw an exception.
  • Open a connection to the database and insert that user into it.
  • Send a welcome email.

How does this violate the single responsibility principle? Well while theoretically this is doing “one” thing in that it registers a user, it’s also handling various parts of that process at a low level.

  • It’s controlling how we connect to a database, opening a database connection, and the SQL statement that goes along with it.
  • It’s controlling how the email is sent. Specifically that we are using a direct connection to an SMTP server and not using a third party API or similar to send an email.

It can become a bit of a “splitting hairs” type argument and I’ve intentionally left the logic statement for checking the username in there as a bit of a red herring. I mean theoretically you could get to the point where you go One Class -> One Method -> One Line. So you have to use your judgement and in my opinion, the admin check there is fine (But feel free to disagree!).

Another way to look at it is the saying “Are we doing one thing only, and doing that one thing well”. Well we are directing the flow of registering a user well, but we are also doing a bunch of database/SMTP work mixed in with it that frankly we probably aren’t doing “well”.

A Class Should Have Only One Reason To Change

Let’s get back to our original definition.

A class should have only one reason to change

If we take the above code, what things could come up that would cause us to have to rewrite/change this code?

  • The flow of registering a user changes
  • The restricted usernames change
  • The database schema/connection details change (Connection String, Table Schema, Statement changes to a Stored Proc etc)
  • We stop using a SQL database all together for storing users and instead use a hosted solution (Auth0, Azure B2C etc)
  • Our SMTP/Email details change (From Email, Subject, Email contents, SMTP server etc)
  • We use a third party API to send emails (Sendgrid for example)

So as we can see, there are things that could change that have absolutely nothing about registering a user. If we move to using a different method of sending emails, we are going to edit the “RegisterUser” method? Doesn’t make sense right!

While the statement of having only “one” reason to change might be extreme, we should work towards abstracting code so that changes unrelated to our core responsibility of registering users affects minimal change to our code. The only reason why our class should change is because the way in which users register changes. But changes to how we send emails or which database we decide to use shouldn’t change the RegisterService at all.

With that in mind, what we would typically end up with is something like so :

You probably already have code like this so it’s not going to be ground breaking stuff. But having split out code into separate classes, we are now on our way to abiding by the statement “A class should only have one reason to change”.

What Does Single Responsibility Give Us?

It’s all well and good throwing out names of patterns and principles, but what is the actual effect of Single Responsibility?

  • Code being broken apart with each class having a single purpose makes code easier to maintain, easier to read, and easier to modify.
  • Unit testing code suddenly becomes easier when a class is trying to only do one thing.
  • A side effect of this means that code re-useability jumps up as you are splitting code into succinct blocks that other classes can make use of.
  • The complexity of a single class often goes drastically down because you only have to worry about “one” piece of logic (For example how a user is registered, rather than also worrying about how an email is sent).

Simply put, splitting code up into smaller chunks where each piece just focuses on the one thing it’s supposed to be doing makes a developers life a hell of a lot easier.

What’s Next?

Up next is the O in SOLID. That is, The Open/Closed Principle.

Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.