Martin Costello's Blog

The blog of a software developer and tester.

Look ma, no Dockerfile! ๐Ÿšซ๐Ÿ‹ - Publishing containers with the .NET SDK ๐Ÿ“ฆ

2 May 2024 by Martin Costello |
2 May 2024 by Martin Costello

A container ship being loaded with the .NET logo on the stern

Containers have been a thing in the software ecosystem for a few years now, with lots of associated technologies and concepts - Docker, Kubernetes, Helm charts, sidecars and many more. Using containers simplifies the deployment of your application by reducing things down to a single artifact that you can deploy along with all the required dependencies, including the operating system, and everything should Just Workโ„ข๏ธ. It's almost like shipping your whole machine off to production!

The cost for that simplicity of deployment is the steeper learning curve for you the developer to understand all these additional concepts and technologies. In addition, you will likely need to revisit how you build your application, creating a Dockerfile to produce a container image that contains everything you need to build and run your application.

The more complicated your build process, the more daunting this becomes - for example, if your application builds client-side assets with a JavaScript toolchain. In that case, you need to install Node.js, npm etc. in the container build image too so you can produce those assets. Things can quickly get complicated, and that's before you even start thinking about things like layer caching, exposing ports, what user to run as and more. ๐Ÿ˜ฎโ€๐Ÿ’จ

What if we could simplify a lot of that complexity and just build our application like we would if we weren't using containers, but then just turn it into a container image? Well, the .NET 8 SDK allows us to do exactly this, meaning you can containerise your application and not need a Dockerfile at all! ๐Ÿšซ๐Ÿ‹

Plus, as a bonus, if building with GitHub Actions, we can leverage this support to attest the provenance of our container images with minimal additional effort. ๐Ÿ•ต๏ธ๐Ÿชช


.NET Native AoT Make AWS Lambda Function Go Brrr

29 November 2023 by Martin Costello |
29 November 2023 by Martin Costello

The AWS Lambda logo overlaid with the .NET logo wth some fire emojis added

Since 2017 I've been maintaining an Alexa skill, London Travel, that provides real-time information about the status of London Underground, London Overground, and the DLR (and the Elizabeth Line). The skill is an AWS Lambda function, originally implemented in Node.js, but since 2019 it has been implemented in .NET.

The skill uses the Alexa Skills SDK for .NET to handle the interactions with Alexa, and since earlier this month has been running on .NET 8.0.0.

I've been using a custom runtime for the Lambda function instead of the .NET managed runtime. The main reason for this is that it lets me use any version of .NET, not just the ones that AWS support. This has allowed me to not only use pre-release versions of .NET for testing, but it also enables me to use the latest versions of .NET as soon as they are released. The only disadvantage of this approach is that I have to patch the version of .NET being used once a month for Patch Tuesday, but I have automation set up to do that for me, so the overhead of doing that is actually minimal ๐Ÿ˜Ž.

As part of the .NET 8 release, the .NET team has put a lot of effort into improving the breadth of the capability of the native AoT support. With .NET 8, many more use cases are supported for AoT, making the performance and size benefits of AoT available to more applications than before. The .NET team at AWS has also been working hard on ensuring that the various AWS SDK libraries are compatible with AoT, with the various NuGet packages now annotated (and tested) as being AoT compatible.

With all these changes, I was curious to see how much of a difference AoT would make to the performance of my Lambda function, so I decided to try it out. In this post I'll go through what I needed to change to allow publishing my Alexa skill as a native application, what I learned along the way, and the results of the changes to the function's runtime performance.

TL;DR: It's faster, smaller, and cheaper to run. ๐Ÿš€๐Ÿ”ฅ

Let's dive in!


Upgrading to .NET 8: Part 6 - The Stable Release

20 November 2023 by Martin Costello |
20 November 2023 by Martin Costello

Last week at .NET Conf 2023, the stable release of .NET 8 was released as the latest Long Term Support (LTS) release of the .NET platform.

With the release of .NET 8.0.0 and the end of the preview releases, my past week can be summed up by the following image:

The All the Things meme, with the text: Upgrade All The Things To .NET 8


Upgrading to .NET 8: Part 5 - Preview 7 and Release Candidates 1 and 2

13 October 2023 by Martin Costello |
13 October 2023 by Martin Costello

This post is a bumper edition, covering three different releases:

I had intended to continue the post-per-preview series originally, but time got away from me with preview 7, plus there wasn't much to say about it, and then I went on holiday for two weeks just as release candidate 1 landed. Given release candidate 2 was released just a few days ago, instead I figured I'd just catch-up with myself and summarise everything in this one blog post instead!

Release Candidate 2 is also the last planned release before the final release of .NET 8 in November to coincide with .NET Conf 2023, so this is going to be the penultimate post in this series.


Upgrading to .NET 8: Part 4 - Preview 6

19 July 2023 by Martin Costello |
19 July 2023 by Martin Costello

Following on from part 3 of this series, I've been continuing to upgrade my projects to .NET 8 - this time to preview 6. In this post I'll cover more experiences with the new source generators with this preview as well as a new feature of C# 12: primary constructors.


Upgrading to .NET 8: Part 3 - Previews 1-5

12 July 2023 by Martin Costello |
12 July 2023 by Martin Costello

In the previous post of this series I described how with some GitHub Actions workflows we can reduce the amount of manual work required to test each preview of .NET 8 in our projects. With the infrastructure to do that set up we can now dig into some highlights of the things we found in our testing of .NET 8 itself in the preview releases available so far this year!


Upgrading to .NET 8: Part 2 - Automation is our Friend

11 July 2023 by Martin Costello |
11 July 2023 by Martin Costello

In part 1 of this series I recommended that you prepare to upgrade to .NET 8 and suggested that you start off by testing the preview releases. Testing the preview releases is a great way to get a head start on the upgrade process and to identify any issues sooner rather than later, but it does require an investment of your time from preview to preview each month.

Even if you don't want to test new functionality, you still need to download the new .NET SDK, update all the .NET SDK and NuGet package versions in your projects, and then test that everything still works (that's already automated at least, right?). This can be a time-consuming process over the course of a new .NET release, and it starts to become harder to scale if you want to test lots of different codebases with the latest preview of the next .NET release.

What if we could automate some of this process so that we only need to focus on the parts where we as humans really add value compared to the mechanical parts of an upgrade?

In part 2 of this series I'm going to explain how I've gone about automating the boring parts of the process of testing the latest .NET preview releases using GitHub Actions.


Upgrading to .NET 8: Part 1 - Why Upgrade?

10 July 2023 by Martin Costello |
10 July 2023 by Martin Costello

Another year, another new major version of .NET is coming - .NET 8, to be specific.

I write that like it's brand new information - it's been coming for a while, what with .NET 8 Preview 1 having being released in Feburary - but it's only recently occured to me to write this blog post series (yes, a series, more on that later).

As annouced a few releases ago, a new major version of .NET is released every November. These alternate between an odd-numbered Short Term Support (STS) release and an even-numbered Long Term Support (LTS) release (see here).

There's a nice graphic here from the .NET website that illustrates how things look today:

A timeline showing the support for .NET 5 in 2020 through to .NET 9 in 2024

That means .NET 8 will be the next LTS release and supercede .NET 6 and also .NET 7 by the end of 2024.

But why should you upgrade to .NET 8? Staying supported and patched is the primary reason, but there's another reason that sounds much more compelling:

"The first thing that you can do to get free performance in your ASP.NET or .NET applications is to upgrade your .NET version."

Damian Edwards


Using the .NET JSON Source Generator with ASP.NET Core Minimal APIs

28 November 2021 by Martin Costello |
28 November 2021 by Martin Costello

I've recently completed upgrading a bunch of personal and work applications to ASP.NET Core 6, and now that the dust has finally settled on those efforts, I thought I'd look into a new feature of .NET 6 that I hadn't tried out yet - JSON source generators.

If you haven't come across them before, C# source generators are a way to write some code that can generate more code during compilation. It's a form of metaprogramming.

One of the benefits of the new JSON source generator for the System.Text.Json serializer is that it is more performant that the APIs introduced as part of .NET 5. This is because the serializer is able to leverage code that is compiled ahead-of-time (the source generator part) to serialize and deserialize objects to and from JSON without using reflection (which is relatively slow).

It sounds like that could give applications a performance boost at runtime, but how can we use the new JSON source generator with ASP.NET Core Minimal APIs?


GitHub Codespaces Gotchas with ASP.NET Core OAuth

15 August 2021 by Martin Costello |
15 August 2021 by Martin Costello

This week GitHub Codespaces was made generally available for Teams and Enterprise, and coupled with the release of the ability to open any repository in Visual Studio Code in a web browser just by pressing ., I thought I'd give it a try with some existing projects. In the process I hit a few gotchas that took me a few hours to get to the bottom of. This post goes through some of those and how to resolve them.