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 back to analyze where we could improve our SDLC as well, in order to reduce friction and help our de...| Anthony Simmon
With a bit of automation, we treat API specifications as first class citizens in our codebases, ensuring they are versioned, validated, and maintained with breaking change detection in our ASP.NET Core projects.| Anthony Simmon
A practical walkthrough for running Python code in C# with CSnakes' source generator.| Anthony Simmon
We built Leap, an opinionated, reliable CLI tool powered by .NET Aspire to make distributed system development easier for all Workleap developers.| Anthony Simmon
xUnit.net v3 finally brings native support for cancellation tokens in tests. Let's see how to use it.| Anthony Simmon
Use the new relationship capabilities in .NET Aspire 9.1 to build a custom Mermaid exporter for generating architecture diagrams that are always up-to-date.| Anthony Simmon
Help software developers do their best work with .NET Aspire, the application development platform that automates onboarding and boosts productivity from day one.| Anthony Simmon
Automate HTTP calls to web pages or APIs by bypassing Cloudflare Turnstile or any captcha using authentication cookies from a web browser embedded in a WPF app.| Anthony Simmon
After 10 years since the original .NET runtime issue, numeric sorting, or natural sorting, will finally be part of .NET 10. Lets explore the new API and alternatives for older frameworks.| Anthony Simmon
Learn how to set up efficient RPC communication between two processes using bidirectional named pipes, well-defined contracts, and structured messages.| Anthony Simmon
Deserialize C# type hierarchies using a dedicated type discriminator key to map YAML values to their corresponding C# types.| Anthony Simmon
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. Azure identity is typically conveyed using an access token. During local development of applications t...| Anthony Simmon
Visualizing, testing, and understanding complex regex patterns has never been easier.| Anthony Simmon
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 whether it will be implemented. After removing the limitations of HTTPS and the use of custom domains with containers in local development, we will now tackle this missing piece of the puzzle. While awaiting an official solution, here is ...| Anthony Simmon
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 practice more complicated. Containers do not share the same hosts file as the host machine and cannot r...| Anthony Simmon
Automate exporting and mounting self-signed certificate authorities into containers for secure HTTPS in local development using .NET Aspire's flexible application model.| Anthony Simmon
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 about each library to help you make an informed decision for your project.| Anthony Simmon
Learn how to replace IdentityModel with MSAL.NET for OAuth 2.0 and OpenID Connect flows using support for generic OIDC-compliant authorities.| Anthony Simmon
Increase the reliability of MSAL.NET with IHttpClientFactory, benefiting from automatic DNS lookup, TCP connection reuse, and HttpMessageHandler pipeline extensibility.| Anthony Simmon
When dealing with client applications, use the official Microsoft file-based token cache for MSAL.NET rather than implementing your own.| Anthony Simmon
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 resource.| Anthony Simmon
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 to use .NET Aspire. # .NET Aspire official documentation The best place to start learning .| Anthony Simmon
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 host.| Anthony Simmon
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 eliminates boilerplate, reduce complexity and allows you to focus on developing your business features.| Anthony Simmon
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 this search on GitHub. .nuspec files can contain references to dependencies, making them important to c...| Anthony Simmon
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 years, while OpenTelemetry.Instrumentation.GrpcNetClient and Azure.AI.OpenAI have never had a stable...| Anthony Simmon
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. According to the Renovate NuGet manager documentation (a manager is a module that manages updates for a ...| Anthony Simmon
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 Aspire is optimized for developers. With the application model, you can use .NET Code to build up an underst...| Anthony Simmon
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 pipeline. To achieve this, we relied on the TreatWarningsAsErrors property, which is already widely...| Anthony Simmon
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 // 1.0.0+9aa8e4c69145f5b7b4b59c93f2a1ee5ea19b79f9 This is a breaking change in the .NET 8 SDK, which now includes Source Link by ...| Anthony Simmon
If you’ve ever encountered the following error, this article is for you: InvalidOperationException: The ‘InnerHandler’ property must be null. ‘DelegatingHandler’ instances provided to ‘HttpMessageHandlerBuilder’ must not be reused or cached. This means you are using the Microsoft.Extensions.Http library and have modified an HttpClient’s handler pipeline by inserting a DelegatingHandler. As the error indicates, you cannot reuse a handler across multiple HttpClient instances. In...| Anthony Simmon
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’s very unlikely that .NET developers will directly expose their Kestrel-based web apps to the internet. Typically, we use other popular web servers like Nginx, Traefik, and Caddy to act as a rever...| Anthony Simmon
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 press the TAB key.| Anthony Simmon
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 .NET, Java, JavaScript, PHP, Python, and many others runtimes.| Anthony Simmon
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 of .NET Aspire. Therefore, it is possible to run Ruby on Rails web applications on it.| Anthony Simmon
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’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 primary key.| Anthony Simmon
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’ characteristics and behaviors, such as authorization policies, CORS (Cross-Origin Resource Sharing) restrictions, filters, and more. In the context of MVC contro...| Anthony Simmon
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’s not possible to “elevate the current process”. In reality, the only thing we can do is to start a new process with administrative rights. In this article, we will explore how to do this with a console application - ...| Anthony Simmon
I have often had to integrate the Azure Storage SDK into various applications, and each time, I’ve done it differently. Here’s an overview of the questions I’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 as containers, tables, or individual queues? Should I create my own abstraction or factory on top of the SDK?| Anthony Simmon
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’s easy to use improper parameters when using PBKDF2. Many .NET developers get inspired by articles written several years ago which are no longer up-to-date with the current security standards. I am writing this article in part to address this issue.| Anthony Simmon
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’ll further explore the possibilities for optimizing the compilation of a .NET solution by focusing on the solution’s architect...| Anthony Simmon
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’s possible that some aspects may have changed by the time you read this article. During the .NET Conf 2023, Microsoft announced .NET Aspire, a new .NET workload designed to ease the development of applications and microservices in a cloud-native context.| Anthony Simmon
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’s specifications. Such a compilation duration has a direct impact on three points:| Anthony Simmon
In this blog post, we’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’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 disposable sandbox to experiment with replication mechanics and fault tolerance in general.| Anthony Simmon
I’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’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 might only pay around $5 per month.| Anthony Simmon
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’re the author of a NuGet package and you’re determined to avoid introducing breaking changes? Ever wonder how Microsoft maintains backwards compatibility in ASP.NET Core for years? There’s of course a lot of design involved, but one tool they use is their Microsoft.| Anthony Simmon
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’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’s .NET Fiddle, Try .NET, the popular LINQPad, the built-in csi.exe, and many more.| Anthony Simmon
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 YamlDotNet. To illustrate these concepts, we’ll examine the specific use case of partially parsing the envi...| Anthony Simmon
In our previous posts, we’ve learned how to build beautiful command-line applications using System.CommandLine and modern dependency injection. There might be situations where you want to monitor how your application is used. The specifics of what telemetry data to gather will largely depend on your application’s nature. Remember, it’s not appropriate to collect personally identifiable information (PII) in publicly available apps, although it might be acceptable if you’re creating an ...| Anthony Simmon
In our last talk about System.CommandLine, we learned how to easily build command line apps using .NET and C#, following most of the advice from CLI guidelines. We also brought in dependency injection to make our code more flexible, easier to read, and simpler to test. Now that we have our basic setup ready, it’s time to improve our user experience. So far, users have been interacting with our app by typing every single argument each time they invoke the app.| Anthony Simmon
System.CommandLine is the official .NET library that provides common functionality for command-line applications. This includes features like argument parsing, automatic help text generation, tab autocomplete, suggestions, corrections, sub-commands, user cancellation, and much more. Many official .NET tools are built on top of System.CommandLine, including the .NET CLI, Kiota, Tye, some Azure tools, and other .NET additional tools. Despite the fact that the library has been in preview for sev...| Anthony Simmon
Validation attributes are an extremely convenient and non-intrusive method of validating data integrity in .NET. All you need to do is decorate your properties, fields, or method parameters to gain access to this functionality. At GSoft, we developed GSoft.ComponentModel.DataAnnotations, which offers even more validation attributes. In this blog post, I will introduce these new attributes to you. # Why use validation in the first place? Validation attributes in .NET are mostly used for perfor...| Anthony Simmon
If you’re using the .NET Application Insights SDK to instrument and monitor your ASP.NET Core or worker service applications, this blog post is for you. We’ll explore some potential causes for data loss in your telemetry, and how to fix them: Losing telemetry data on application shutdown Not capturing application logs Failing to capture end-user information in the ASP.NET Core authentication middleware Not capturing personal identifiable information (for internal web applications only) Ca...| Anthony Simmon
Since the release of .NET 6, we’ve heard a lot about ASP.NET Core minimal APIs. They’ve been discussed at Microsoft conferences, in blog posts, in YouTube videos, and on social networks. We’ve all seen this kind of code sample of a minimal API: var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.MapGet("/", () => "Hello World!"); app.Run(); This is significantly more concise than controller-based web APIs, and we can all agree on that.| Anthony Simmon
During my recent visit to the Microsoft offices in Montréal for a meetup organized by the MSDEVMTL Meetup group, I had the opportunity to learn more about Kiota, an incredible tool developed by Microsoft. The Kiota development team showcased its capabilities and demonstrated how it streamlines the process of generating client SDKs for various APIs. Kiota is an OpenAPI-driven code generation tool that enables developers to create SDKs in different programming languages.| Anthony Simmon
If you’re developing .NET applications that integrate with Microsoft Azure resources, such as Key Vault, you’re probably familiar with the DefaultAzureCredential class from the Azure.Identity library. This class simplifies the process of authenticating against Azure services by providing a unified way to retrieve access tokens. However, when working in a local development environment, you might have noticed that DefaultAzureCredential can take up to 10 seconds to retrieve your Azure CLI c...| Anthony Simmon
Configuration in .NET is a powerful pattern that allows .NET developers to manage application settings from various sources, such as JSON files, environment variables, and more. However, sometimes developers need a way to reference and substitute configuration values from other settings, which is not provided out of the box. That’s where the GSoft.Extensions.Configuration.Substitution library comes in! In this blog post, we will explore how the GSoft.Extensions.Configuration.Substitution li...| Anthony Simmon
At every major release of the ShareGate Migration Tool (SGMT), a part of the development team spends a few hours to do regression testing. These tests cannot be automated using UI testing tools such as Cypress, Playwright and Selenium because SGMT is a desktop application made in WPF. I started looking for UI testing solutions for desktop applications. I quickly discarded expensive UI testing suites. WinAppDriver was very interesting, but one of the requirements was to add some kind of identi...| Anthony Simmon
| Anthony Simmon
If you are a programmer, you may have heard of the SOLID principles. This acronym, among others like TDD, DI, etc. is unfortunately more and more used as buzzwords. It is not rare to hear a candidate quoting the definition of the SOLID principles in a technical interview: single responsibility, dependency inversion… However, the most interesting part may be how to effectively use them everyday. Robert C. Martin promoted the SOLID principles around 2003.| Anthony Simmon
This post was originally published in 2016 and may contain outdated information. ServerPilot is a cloud hosting control panel designed to be simple, efficient and available as a service. It installs everything you need to run your PHP websites and web applications in a few minutes, with a production-ready configuration on your VPS or dedicated server. In my current company, we started using ServerPilot to host every PHP websites or web applications of our clients.| Anthony Simmon
This post was originally published in 2016 and may contain outdated information. I’m proud to annonce the release of Pillar, a lightweight MVVM framework for Xamarin.Forms 1.x and 2.x. With this framework, you won’t have to deal with page navigation or messed up code-behind anymore. Now, it’s all about view models, and navigation between view models. It rely on Autofac for dependency injection and MvvmLight for basic MVVM features and helper classes.| Anthony Simmon
This post was originally published in 2016 and may contain outdated information. Being able to run ASP.NET web applications or web sites on Linux operating systems now is very cool. Before that, we had to use Mono, but it does’t support the full .NET framework or .NET technologies such as MVC or async support. Now, we have the .NET Core 5.0 (dnxcore50), and we can run our cross-platform ASP.NET Core web apps with the same new web server, Kestrel.| Anthony Simmon
This post was originally published in 2015 and may contain outdated information. After many adjustments, I finally manage to score 100/100 on Google PageSpeed Insights. If you use WordPress, you will notice that the difficulty will depend on your current theme and installed plugins. In my case, I started with a score of 51 on mobile and 72 on desktop. In this post, I will present a summary of the steps I followed to get the best score on this tool.| Anthony Simmon
This post was originally published in 2015 and may contain outdated information. MuPDF is a small, fast and free PDF library written in portable C, available for Android. You can use this library for its built-in PDF viewer, for rendering PDF pages to images with a high-quality, manipulating PDF files in various ways… It supports PDF 1.7 with transparency, encryption, hyperlinks, annotations, searching and more. It also reads OpenXPS documents.| Anthony Simmon
This post was originally published in 2015 and may contain outdated information. Designing a login form with Ionic Framework is very easy. I wrote this post for two reasons: First, I find vertically and horizontally centered login forms in mobile applications beautiful, especially with a nice background image or pattern. Secondly, I wanted a responsive login form that looks great on tablets. Many people use Ionic Framework to develop smartphone-only applications, but it is possible to make th...| Anthony Simmon
This post was originally published in 2015 and may contain outdated information. In this post I’ll show you how to get Oracle SQL query results to CSV format into a CLOB only by calling stored procedures. This CLOB can be stored later in a table row or in a file using UTL_FILE. There are two stored procedures: The first one, cursor_to_csv, takes a cursor as parameter The second one, query_to_csv, takes a VARCHAR2 # Usage Using a cursor:| Anthony Simmon
This post was originally published in 2015 and may contain outdated information. In many cases, using a caching mechanism can drastically improve performances. Processed results of methods can be stored in memory or in files so they are ready to be returned immediately when we call the methods again. In some .NET applications, we can use the MemoryCache class from System.Runtime.Caching to store data in memory. However, using such library in a basic way may induce some problems such as:| Anthony Simmon
This post was originally published in 2015 and may contain outdated information. This component is a part of Pillar, a lightweight MVVM framework that I made for Xamarin.Forms 1.x and 2.x. Please check it out on NuGet or GitHub. An EventToCommand behavior can be used to bind any event on a visual element to an ICommand. Typically, this element is used in XAML to connect the attached element to a command located in a ViewModel.| Anthony Simmon
| Anthony Simmon
# .NET Conf 2023 local event in Montreal, at the Microsoft Offices On Tuesday, December 19, 2023, during a Meetup organized for the .NET Conf 2023, I had the privilege of presenting the new features of .NET 8, C# 12, and .NET Aspire to members of the Montreal developer community.| Anthony Simmon
Test, validate and troubleshoot your Renovate configuration files locally, without having to push changes to your source control.| Anthony Simmon
Get reproducible builds locally, in your CI, and Docker builds with .NET SDK maintenance via global.json and automatic dependency updates.| Anthony Simmon