RSSAmplifier

Blog

Anthony Simmon

Recent content on Anthony Simmon

anthonysimmon.comRSS feed ↗73 posts

Latest posts

How we enforce .NET coding standards at Workleap to improve productivity, quality and performance

In today’s competitive software development landscape, organizations are actively looking to optimize their Software Development Life Cycle (SDLC) to deliver faster, with better quality, and reduce friction. The rise of Generative AI amplifies this trend even more. Teams that know how to leverage these tools and practices achieve unprecedented velocity. At Workleap, we decided to take a step…

How we enforce web API standards and guidelines at Workleap

Creating a web API means making a promise about the shape of the data exchanged between the API and its consumers. While behavioral aspects are also important, they often require more complex testing strategies, such as integration tests. When it comes to the contract, however, we can leverage tools to ensure that the API adheres to the expected standards, does not break existing consumers, and…

Embed Python in .NET applications to run models with transformers

The Python ecosystem is rich in libraries for natural language processing. As a .NET developer, it can be frustrating to miss out on all the possibilities offered by the Python community. Hugging Face, Jupyter notebooks, and many resources may seem out of reach. Efforts have been made to address this gap - Semantic Kernel , Microsoft.Extensions.AI , ML.NET , etc. - but the Python ecosystem remains…

How Workleap uses .NET Aspire to transform local development

Jessica just joined the team as a developer. After cloning her team’s repos, she runs a single command in her terminal: leap run . Within minutes, she’s looking at a fully functioning dashboard showing a microservice architecture with backends, frontends, databases, and messaging services - all running locally on her machine. “That was easy”, she thinks, unaware that months…

Handle cancellation in tests with xUnit.net v3

Some tests may take a long time, and cancelling them in your IDE or CI might require some delay. File accesses, HTTP requests, database calls, delays, etc. can occur when you decide to interrupt the ongoing test run. In some IDEs, like Rider, you can stop a test run, but the currently running tests will continue until they are finished. This is why the “Stop” button sometimes becomes…

Generating architecture diagrams from .NET Aspire resources at publish time

Software architecture diagrams tend to age poorly, often becoming obsolete as soon as actual implementations start diverging from the initial design. They struggle to keep up with the continuous evolution of code, dependencies, and business requirements. Maintaining them requires discipline and rigor, which are often lacking in software development projects. Ideally, there would be a way to…

.NET Aspire improves developer onboarding while reducing costs

Reading outdated documentation for days. Chasing colleagues for missing information. Trying to run scripts that are no longer maintained. Waiting a week for IT to provide access to certificates and secrets. Requesting database dumps because seeding scripts are out of sync. Finally merging your first contribution after a month - these are common frustrations that new developers face when joining a…

Authenticating HTTP requests with cookies from an embedded WebView2 browser in WPF

Authenticating HTTP requests using cookies from an embedded browser in a desktop application can be useful for automating tasks on websites protected by Cloudflare Turnstile . This article demonstrates how to extract cookies from a WebView2 control and add them to the headers of an HttpRequestMessage in a WPF application. To achieve this, we need to create a DelegatingHandler that holds a…

Numeric sorting in .NET

Numeric sorting, also often known as natural sorting, organizes strings in a human-logical order, considering numbers atomically. With default sorting algorithms, “v10” would be sorted before “v3” because the comparison happens character by character, while in numeric sorting, “v3” would be sorted before “v10” because “3” is considered…

Local inter-process communication over named pipes with ASP.NET Core or StreamJsonRpc in .NET

In simple scenarios of communication between two processes on the same machine , one process can start another and pass information via environment variables or command-line arguments. It can also receive the execution result through return codes or standard output. However, in more complex situations, a communication channel must be established and maintained between the two processes for as long…

Polymorphic deserialization with YamlDotNet

Suppose you have a Shape class and derived classes Rectangle , Circle , and Triangle : public abstract class Shape ; public sealed class Rectangle : Shape { [YamlMember(Alias = 'width')] public int? Width { get ; set ; } [YamlMember(Alias = 'height')] public int? Height { get ; set ; } } public sealed class Circle : Shape { [YamlMember(Alias = 'radius')] public int? Radius { get ; set ; } } public…

Better Azure Identity authentication support and performance during local development with .NET Aspire

In Azure, accessing protected resources is often achieved via connection strings or access keys. While these provide a level of protection, they may not be sufficient for some organizations. Another option is to use Azure identities . Combined with role-based access control (RBAC), Azure identity authentication ensures that only specific individuals or systems can access particular resources .…

Visualize and test your regular expressions with debuggex.com

I love regular expressions. It’s one of the first things I learned as a programmer. They represent an intriguing mix of intellectual challenge and expressive power. Regexes can condense complex logic into a single line, creating a mental puzzle that feels both elegant and satisfying to solve. That said, most developers I know don’t share my enthusiasm. Regexes can be hard to read,…

Use non-localhost endpoints for .NET Aspire resources

Since Aspire 9.2 , it is possible to specify custom URLs (non-localhost) for resources without the technique described in this article. In .NET Aspire 9 and earlier versions, resource endpoints can only use localhost in run mode. This can cause issues if you use custom domains for local development . This feature has been requested in GitHub issue #5508 and #4319 , but it’s currently unknown…

Make containers aware of custom local domains on the host machine using .NET Aspire

In my first job as a developer, we used custom hosts for local development with IIS. This allowed us to get a bit closer to the production configuration. We had to edit our C:\Windows\System32\drivers\etc\hosts file and add an entry for each host mapped to the IP address 127.0.0.1 . Overall, this worked well. Nowadays, the introduction of containers into the local development flow makes this…

Enabling automatic trust for self-signed certificates in containers during local development with .NET Aspire

HTTPS in local development can be challenging, especially when using containers. We typically use self-signed certificates during local development, and containers don’t automatically trust these certificates. As a result, many developers default to using HTTP when communicating between containers or between a container and the host machine, or worse, they disable certificate validation…

Benchmarking .NET libraries for image resizing: which performs best?

In this article, we will compare the performance of four .NET libraries for image resizing and determine which one is the fastest and most efficient for this task. The libraries we will compare are: ImageSharp Magick.NET NetVips SkiaSharp First, I will explain the benchmark setup. Then, I will present the code and results obtained for each library. Before concluding, I will provide more details…

Replacing IdentityModel with MSAL's support for generic OIDC-compliant authorities

When it comes to implementing OAuth 2.0 and OpenID Connect authentication flows in .NET applications, there are often two ways to do it. The first, which I would never recommend, is to do it manually by making all the necessary HTTP calls. The second is to use a third-party library that implements these flows in a secure and performant manner. Among the most popular third-party libraries is…

Overriding MSAL's HttpClient with IHttpClientFactory

The default behavior of MSAL.NET is to create its own static singleton instance of HttpClient . This HttpClient is then shared among different instances of IPublicClientApplication and IConfidentialClientApplication and used to make HTTP requests for various authentication flows. However, it is preferable to provide your own instance of HttpClient for performance, reliability, and control reasons,…

Secure cross-platform and file-based token cache for MSAL.NET

There is nothing more annoying than having to authenticate every time you launch an application. To avoid this, developers often implement a caching system to store authentication tokens. That being said, this cache must be sufficiently secure to prevent an attacker from retrieving and exploiting them. This is particularly true for client applications (console and desktop), when the tokens are…

Programmatically monitoring and reacting to resource logs in .NET Aspire

I was recently asked if it is possible to obtain the ID of a container orchestrated by .NET Aspire to monitor its logs. The answer is yes, and in this article, we will see two ways to achieve this by retrieving the logs of an arbitrary MongoDB resource named mongo and displaying them in the console. The first method will be specific to containers, while the second method can be applied to any…

Automate your .NET SDK updates for consistent and reproducible builds with global.json and Renovate

This is the story of Tom, a .NET developer who has just finished implementing a new feature in an ASP.NET Core application. Everything works perfectly on his machine, and he submits his code via a pull request. However, the CI pipeline fails to compile due to an IDE0100 error. Not understanding the cause of the problem, Tom asks for help from his colleague Brian, who is able to reproduce it.

Must-have resources for new .NET Aspire developers

Six months after its first preview released during .NET Conf 2023, .NET Aspire becomes generally available (GA) at Microsoft Build 2024. This project, which aims to revolutionize the local development of distributed applications, has unfortunately been overlooked by some due to its preview status. This is good news for those who can now embark on the adventure. Here are some resources to learn how…

Disabling .NET Aspire authentication to skip the login page

Preview 6 of .NET Aspire introduced a login page to access the dashboard. Unless the dashboard is launched from Visual Studio or Visual Studio Code (with the C# Dev Kit extension ), the login page will appear and prompt for a token. For scenarios where the dashboard is started via dotnet run or from the Docker image, the token can be retrieved from the console window that was used to start the app…

.NET Aspire is the best way to experiment with Dapr during local development

Not interested in reading the full article? Check out the complete code sample on GitHub instead. Dapr provides a set of building blocks that abstract concepts commonly used in distributed systems . This includes secured synchronous and asynchronous communication between services, caching, workflows, resiliency, secret management and much more. Not having to implement these features yourself…

Configure Renovate to handle nuspec files

I recently mentioned that Renovate’s NuGet manager only supports certain files by default , and .nuspec files are not among them. These are XML manifests that describe the metadata of a NuGet package . Although nowadays, SDK-style projects are sufficient for most cases to describe and generate NuGet packages, there are still many very popular projects that rely on .nuspec files, as shown by…

Configure Renovate to update preview versions of NuGet packages

By default, Renovate ignores preview versions of dependencies. For NuGet, a preview version is a package whose version contains a semantic suffix such as -alpha , -beta , -rc . There are some well-known NuGet packages that are only available in preview versions. For example, Aspire.Hosting will likely remain in preview until the release of .NET 9, StyleCop.Analyzers has been in beta for already 5…

Automated NuGet package version range updates in .NET projects using Renovate

In my previous post about how to locally test and validate Renovate configuration files , we saw how Renovate can be helpful in keeping our dependencies up-to-date. It recommended updates for the Microsoft.Extensions.Hosting package from 7.0.0 to 7.0.1 (minor) or 8.0.0 (major). By default, the way Renovate handles NuGet package updates in .NET projects is suitable for the majority of cases.…

Referencing external Docker containers in .NET Aspire using the new custom resources API

Up until now, the application model of .NET Aspire was limited to two types of resources , namely executables and containers . The underlying DCP (Developer Control Plane) orchestrator is responsible for managing the lifecycle of these resources, including their creation, start, stop, and destruction. David Fowler recently tweeted about the extensibility of the application model : “ .NET…

TreatWarningsAsErrors and warnaserror are not the same

At work, my team recently developed a custom MSBuild task designed to extract the OpenAPI specification from an ASP.NET Core application during compilation and validate it against our API design guidelines with Spectral . When a Spectral rule is violated, the MSBuild task generates a warning. To ensure developers fix these issues, we planned for these warnings to be treated as errors in their CI…

Locally test and validate your Renovate configuration files

Renovate is an automated dependency management tool that can be used to keep your dependencies up-to-date. It can be configured to automatically create pull requests to update your dependencies, and it supports a wide range of package managers and platforms. To use Renovate, you need to create a renovate.json configuration file . The creation process can take some time, as there are many…

Remove git hash from assembly informational version in .NET 8

If you build your .NET projects with the .NET 8 SDK, you may have noticed that the assembly informational version now includes the git hash of the associated commit : var informationalVersion = typeof ( Program ). Assembly . GetCustomAttribute < AssemblyInformationalVersionAttribute >() . InformationalVersion ; Console . WriteLine ( informationalVersion ); // Prints something like //…

Your custom HttpClient delegating handlers should be transient

If you&rsquo;ve ever encountered the following error, this article is for you: InvalidOperationException: The &lsquo;InnerHandler&rsquo; property must be null. &lsquo;DelegatingHandler&rsquo; instances provided to &lsquo;HttpMessageHandlerBuilder&rsquo; must not be reused or cached. This means you are using the Microsoft.Extensions.Http library and have modified an HttpClient &rsquo;s handler…

How to securely reverse-proxy ASP.NET Core web apps

Kestrel is the solid, fast, and reliable web server that powers ASP.NET Core applications. It is entirely capable of serving as a front-facing web server, as proven by the Azure teams when they chose Kestrel and YARP to handle reverse-proxying all services hosted on Azure App Services . However, it&rsquo;s very unlikely that .NET developers will directly expose their Kestrel-based web apps to the…

Enable tab completion for the .NET CLI in your terminal

Have you ever forgotten the name of a .NET command or the necessary arguments to execute it? Even though using the -h parameter can often bail us out by reminding us of the commands, arguments, and descriptions, this process can sometimes feel a bit tedious. You might not know this, but the .NET CLI includes an autocomplete feature, which can complete or suggest commands and arguments when you…

.NET Aspire dashboard is the best tool to visualize your OpenTelemetry data during local development

The .NET team recently released the Aspire dashboard as a standalone Docker public image . This can be easily used as an OpenTelemetry exporter to collect and display the traces, metrics, and structured logs generated by your applications during local development . The Aspire dashboard can be used to visualize telemetry emitted by any application using the OpenTelemetry SDK which is available for…

Running Ruby on Rails web apps with .NET Aspire

The Microsoft ecosystem is not kind to Ruby developers. The Ruby SDK for Azure was retired in February 2021 , and the support for Ruby in the OpenAPI client generator Kiota is extremely limited , if not unusable. However, .NET Aspire is a special case. This ambitious local development orchestrator is not tied to any specific technology, as I explained in my previous article on the inner workings…

Key derivation in .NET using HKDF

Key derivation is a process that allows you to create one or more keys from a single primary key. Rather than storing multiple individual keys that serve different purposes, it&rsquo;s possible to derive them as needed from a primary key. For example, to use the AES algorithm for encrypting data with HMAC authentication for a specific user, you can derive an AES key and an HMAC key from a single…

Implementing fine-grained access control with ASP.NET Core custom endpoint metadata

Endpoint metadata are pieces of information associated with each endpoint in an ASP.NET Core application. An endpoint is essentially an entry point into your web application, such as an MVC controller action or a route in a minimal API, which can process HTTP requests. Endpoint metadata allow for the description of these endpoints&rsquo; characteristics and behaviors, such as authorization…

Programmatically elevate a .NET application on any platform

There are times when your .NET program needs to perform an operation that requires administrative rights (elevated privileges). An example could be modifying the hosts file ( C:\Windows\System32\drivers\etc\hosts on Windows or /etc/hosts on Linux and macOS). Technically, it&rsquo;s not possible to &ldquo;elevate the current process&rdquo;. In reality, the only thing we can do is to start a new…

Best practices for integrating the Azure Storage SDK into your .NET applications

I have often had to integrate the Azure Storage SDK into various applications, and each time, I&rsquo;ve done it differently. Here&rsquo;s an overview of the questions I&rsquo;ve asked myself over time: Should I register a BlobServiceClient instance in the dependency injection service? What if I need to use multiple storage accounts? How do I manage multiple clients for different resources, such…

Evolutive and robust password hashing using PBKDF2 in .NET

PBKDF2 (Password-Based Key Derivation Function) is a key derivation function that is often used for password hashing . Password managers such as 1Password and Bitwarden rely on it. This is also how ASP.NET Core Identity stores user passwords. It&rsquo;s easy to use improper parameters when using PBKDF2. Many .NET developers get inspired by articles written several years ago which are no longer…

Optimizing .NET solution architecture for faster compilation through project decoupling

In the previous article , we discussed how to identify Roslyn analyzers that have a negative impact on the compilation time of a .NET solution . For some projects, this can represent a significant percentage of the compilation time, which can affect developer productivity and satisfaction, as well as metrics related to performance and releases. In this next part, we&rsquo;ll further explore the…

Exploring the Microsoft Developer Control Plane at the heart of the new .NET Aspire

Since Aspire 9.3 release in May 2025, there is now an official documentation about the Microsoft Developer Control Plane (DCP) , although it does not cover all aspects in detail. As I write this, less than a week after the end of .NET Conf 2023 and the release of .NET 8, .NET Aspire is in preview version ( 8.0.0-preview.1.23557.2 ). Therefore, it&rsquo;s possible that some aspects may have changed…

Optimizing C# code analysis for quicker .NET compilation

As a .NET solution grows, the time spent on Roslyn analyzers during compilation increases. I have witnessed a web solution where the execution time of the Roslyn analyzers was simply absurd. In particular, the ratio was 70% of the time spent on the Roslyn analyzers and 30% on the rest of the compilation. The total build time was about 2 to 3 minutes depending on the machine&rsquo;s specifications.…

The only local MongoDB replica set with Docker Compose guide you'll ever need!

In this blog post, we&rsquo;re going to explore different Docker Compose setups for you to run a MongoDB replica set locally . Replica sets are a must-have for anyone wanting to leverage MongoDB&rsquo;s powerful features like transactions , change streams , or accessing the oplog . Locally running a MongoDB replica set not only grants you access to these functionalities but also serves as a…

Your own private ChatGPT in hours? Azure Chat makes it possible!

I&rsquo;ve been using ChatGPT Plus for many months now. Like many others, I use it for simple tasks like spell-checking and more complex ones like brainstorming. It&rsquo;s been great for my personal and work projects. But I wonder if the USD $20 per month fee is worth it for how often I use it. I only interact with ChatGPT a few times a week. If I used the OpenAI API , which charges as you go, I…

Preventing breaking changes in .NET class libraries

Have you ever felt frustrated when updating a NuGet package, only to have your build fail because the new version of the package introduced a breaking change? Or perhaps you&rsquo;re the author of a NuGet package and you&rsquo;re determined to avoid introducing breaking changes? Ever wonder how Microsoft maintains backwards compatibility in ASP.NET Core for years? There&rsquo;s of course a lot of…

The best C# REPL is in your terminal

A Read-Eval-Print-Loop (REPL) is an interactive program that reads your input, evaluates it, prints the result, and loops back to the beginning. It&rsquo;s a great way to experiment with a programming language and an excellent method for learning a new language. C# has many REPLs; some are web-based, others are desktop applications, and some are command-line tools. There&rsquo;s .NET Fiddle , Try…

Convert complex YAML to .NET types with custom YamlDotNet type converters

When it comes to YAML serialization and deserialization in .NET, YamlDotNet is a go-to library with over 100 million downloads on NuGet . It is also integrated into various projects by Microsoft and the .NET team , despite the absence of an official Microsoft YAML library for .NET. In this blog post, we will explore the process of creating custom YAML serializers and deserializers using…