Blog
I came across a situation where I had some dependencies which needed to run some code at launch. In this instance I wanted to register an event type at the application level for use in validation further down the line.
So achieve this is deceptively simple; we make use of a hosted service and scan our assembly for instances with a certain attribute.
The attribute, which we'll call Preload, doesn't contain any code and is just used to tag a class:
[AttributeUsage(AttributeTargets.Class)]
public class PreloadAttribute : Attribute
{
}
Then we use reflection on the start method of our hosted service to find the tagged types and then use the DI framework to get an instance of them:
public class InstantiationService(IServiceProvider serviceProvider) : IHostedService
{
public Task StartAsync(CancellationToken cancellati
Posted on Monday the 12th of January 2026
Read more...
When using unit test frameworks like xUnit the lifetime of the data you set up, for the most part, exists only in memory for the duration of that one unit test. This means that each test is run in isolation and does not affect the other tests. Or, at least, that's how they should be written.
When dealing with databases in integration tests, however, this can be tricky as the database keeps its state between test runs. This means that data which is added or manipulated remains in that state for the next test run. This can make it harder to ensure a consistent scenario each time, especially when tests are run in parallel and you cannot guarantee execution order.
Rather than trying to work around this by making sure I reference unique IDs, which can increase difficulty writing tests as the suite grows, I took the approach of using one database per test. Surprisingly, it's still pretty quick.
In this example I'll be making use of Reqnroll, which [took the
Posted on Friday the 5th of September 2025
Read more...
Sometimes you want to cast between two types that share the same parent. In one of my resent cases I had two settings objects which shared a parent and I wanted to create a second object from the first and keep the parent data.
Take the following code:
record Parent {
public string Surname { get; init; }
public string Location { get; init; }
}
record Son : Parent {
public string Forename { get; init; }
}
record Daughter : Parent {
public int Age { get; init; }
}
Say you had a Son object and wanted it to be a Daughter and keep the Surname and Location from Parent. You would have to map the fields manually. Fine if you have the one instance of this behaviour with one set of objects, but what if you want to do this repeatedly using different types? I had an ever increasing set of cases where I wanted to move data between object types whilst keeping parent data, so I wrote this method:
public static class ObjectExtensions
{
Posted on Monday the 7th of July 2025
Read more...
I recently had to move some clients of an API over from an old endpoint URL to a new one. The new endpoint had completely replaced the old one, with the old endpoint simply being a Route attribute acting as an alias. Having two endpoints for identical functionality was causing confusion, so I couldn't just leave it there despite how harmless it seemed. I also wanted to make this switch at different times for each environment to get people to ensure it's fixed in our pre-production environments before it was fully turned off in prod. In order to facilitate this switch I created a ASP.NET "convention" to allow me to switch this off with a feature flag in appsettings.json.
Here's the "convention" code:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
namespace Glorious.Api;
public class ConditionalControllerAliasConvention<T> : IApplicationModelConvention where T : ControllerBase
{
private readonly string _aliasRoute;
private
Posted on Friday the 9th of May 2025
Read more...
Here's a small method to aid test readability when dealing with sequential numeric ranges:
public static class IntExtensions
{
public static IEnumerable<int> To(this int min, int max)
{
for (int i = min; i < max + 1; i++)
{
yield return i;
}
}
}
It can be used like so:
var range = 2.To(16);
You could have a test like:
var range = 2.To(16);
var expectation = new[] { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
range.Should().BeEquivalentTo(expectation);
In my case it was used for testing methods that group values in ranges by threshold values. Rather than typing out the ranges each time, I made this method to make it less tedious to both read and write.
Posted on Friday the 28th of February 2025
Read more...
In order to accommodate working from the van better, I decided to install a 4G antenna and WiFi router. The idea is that, while a phone does work very well, a dedicated antenna outside the Faraday cage that is a van would improve the chances of actually getting a signal vs a phone.
The antenna is a Poynting MIMO-3-12, which is a 2x2 MIMO 2G/3G/4G/LTE/5G antenna. The router is a Huawei B535. There is a small irony in that the router has a 4x4 antenna, which is faster than 2x2, but it isn't quite as strong.
Installing this did require another hole in the roof...
Installation
.
Here is the script to do it (warning, I'm not much of a bash scripter):
#!/bin/bash
Posted on Friday the 16th of June 2023
Read more...
Sorry this update has taken so long to make it out, but this happened:
Yeah. The van had an engine swap. There were a series of issues which made it more economical long-term to get a younger engine with fewer miles.
Issues were thus:
- The turbo was on its way out
- Oil leak
- Oil pressure warning
- Coolant leak
- The cam belt needed replacing, which requires dropping the engine anyway
So, given the engine was going to get dropped to replace the cam belt, I figured that replacing the engine was the route to go down given the other issues.
On top of this the gearbox also died on me and that needed replaced. I'd rather it didn't happen at the same time... Naturally having to organise this and source parts and stuff took quite a long time. Finding an engine was super hard and finding someone local to
Posted on Thursday the 3rd of November 2022
Read more...
I thought the last post was a big one, but I never imagined this one to be such a mission. This part of the build was done in two stages; one to get a usable toilet and shower for going away on holiday in summer, and then finishing it all off.
Bed partition
So the build is being done from the back to the front, as the design hangs off the bed frame as a core structural component. The first part to this is the partition separating the "bedroom" from the rest of the space. This also acts as the walls for the garage.
First step is to template the wall of the van
Cut and test fit the first stage of the partition
![Fill in the other side](https://uploa
Posted on Monday the 27th of December 2021
Read more...
This is a big one. These tasks were all completed in parallel to each other. I'm going to try and group things together in some coherent order, but the images will not always be presented in chronological order.
The Bedroom
A prerequisite of creating the bedroom is to panel up the garage. For this I used the existing ply lining that came with the van.
Both panels screwed in place
Plywood strip to cover the beam
To support the bed there are two lengths of aluminium angle, 50x50x5mm thick, on each side of the van which are bolted to the main beam using rivnuts. I used existing bolts
Posted on Sunday the 18th of July 2021
Read more...