Skip to main content

Posts

Showing posts from May, 2023

Software Design - Private by default

An important aspect in building maintainable software is the concept of encapsulation. Encapsulation allows us to build modular solutions where internal details (and complexity) are hided behind well-defined interfaces. Visual Studio helps us with this by creating a new class internal by default: Unfortunately, I noticed that most developers immediately change the access modifier to public or even change the default in their IDE(to create public classes by default). If everything is public, there is no encapsulation. Therefore we should definitely change the approach to private by default . In .NET we are rather limited in our options to provide module encapsulation and can only really achieve it at the assembly level (through the internal access modifier). More information: Access Modifiers - C# Programming Guide | Microsoft Learn

.NET 7–Serialize private fields and properties

While doing a code review I noticed the following comment on a public property of a message contract class: Although I have other concerns about the design of this class and why this property should not be part about this message contract, I want to focus on the comment itself. Starting from .NET 7, the comment is no longer correct and you CAN serialize private (and internal) properties. It does not work out of the box(the default still is to ignore private fields and properties), but the necessary extension points are in place to change this behavior. The way to do this is by writing your own Modifier. A modifier is an Action<JsonTypeInfo> or a method with a JsonTypeInfo parameter that gets the current state of the contract as an argument and makes modifications to the contract. Serialize internal properties Let us create an example modifier that allows the serialization of internal properties. We first create our modifier method: To use this modifier we need t...

Stop using pull requests!

Yes, I know. A little bit of controversy in the title of this post could have triggered your attention. But hear me out. I think that the pull request model is a good fit for open source development where people are working in their spare time on projects and want to design, collaborate and review in the open before accepting changes. I don't want to go in too much detail, so if you want to learn more about this model, check out the documentation on Github or the Atlassian BitBucket website. Let me focus on the reason when and why I don’t like to use pull requests. I don’t think they are a good fit for dedicated software development teams working in close collaboration fulltime on the same codebase. In these teams I see pull requests used as a quality control mechanism allowing another (senior) developer to review the changes before approving them and pushing them to the master branch. Pull requests are not a good fit for dedicated software development teams working in c...

Bootstrap 5 - Goodbye jQuery

Bootstrap 5 is the first Bootstrap version that no longer has a dependency on jQuery. Of course some plugins and components still require vanilla JavaScript to function but none of them require jQuery. The Bootstrap framework , originally developed and open-sourced by Twitter, has been an indispensable tool for web developers. It provides a ready-to-use set of UI components and a grid system essential for adaptive web pages that need to display well across PC and mobile browsers. Since its inception, Bootstrap has always had a dependency on the jQuery framework. The jQuery framework , originally created in 2006, is one of the most popular JavaScript frameworks of all time. It provides powerful language features and cross-browser compatibility in an era when web technologies are going through many challenges and experimentations to support a variety of use cases ranging from interactive web pages, single-page apps, AJAX requests, and mobile web apps. With JavaScript standards and...

.NET Core–Monitor cache misses

Caching is an important tool in your toolbox as a developer. When used correctly in can vastly improve performance. However don't introduce caching blindly, it is crucial to monitor your cache usage to see if your caching strategy works and provides the benefits you expect. With .NET 7 this became a little bit easier, thanks to the introduction of MemoryCacheStatistics that holds cache hits, misses, and estimated size for IMemoryCache. You can get an instance of MemoryCacheStatistics by calling GetCurrentStatistics() on your IMemoryCache. instance when the flag TrackStatistics is enabled. If you construct the IMemoryCache instance yourself you can do this by specifying it through the MemoryCacheOptions object: Or if you are using Dependency Injection, you can do this: Now I can create my own EventSource implementation that reads the data from the MemoryCacheStatistics : I created a small console application that reads and writes some value to an IMemoryCache ...

Bootstrap 5 - Show/hide images on specific breakpoints

I'm working on upgrading an existing application from Bootstrap 4 to Bootstrap 5. I used the occasion to clean up the CSS logic. One thing I had in the original application was an image in the header that should be cropped on smaller screens. This how the header looks like on bigger screens: And this is on smaller screens: The trick I used originally was by using a media queries: However with the upgrade to Bootstrap 5 I would try to achieve the same thing using the built-in grid system and breakpoints. Breakpoints Breakpoints are the building blocks of responsive design in Bootstrap. You can use them to control when your layout can be adapted at a particular viewport or device size. Bootstrap includes six default breakpoints, sometimes referred to as grid tiers , for building responsively. These breakpoints can be customized if you’re using our source Sass files. Breakpoint Class infix Dimensions X-Small No...

Visual Studio 2022 17.6–Http Endpoint explorer

I occasionally switch to Jetbrains Rider and Visual Studio Code, but my favorite IDE is and remains Visual Studio(especially with the Github Copilot integration ).  With the 17.6 release a new feature was introduced; the Endpoints explorer. With the Endpoints explorer, you can view and interact with the API endpoints defined in your solution. To use this feature go to View –> Other Windows –> Endpoint Explorer: You get an overview of all the API endpoints available in your solution and the available API calls that can be made: If you right click on an API call, you can choose between Open in the editor to jump to the implementation of the API call or Create Request . This will create a new HTTP file that can be used to execute the specific request on the endpoint: Nice!

Azure Artifacts–NU1301 error

I got contacted by a colleague who asked my help to fix the following error message he gots when executing his build pipeline using Azure Pipelines: error NU1301: Unable to load the service index for source https://tfs.server.com/tfs/DefaultCollection/_packaging/797f899f-9ad1-4158-93bc-8f3293cf4a59/nuget/v3/index.json. This problem turned out to be similar to a problem I had before . Although the error message was not the same and we got less details about the root cause, I could apply the same solution. I had to uncheck the " Limit job authorization scope to current project " toggles in the Project Settings: To get all the details, check out the original post: Azure Pipelines error - User lacks permission to complete this action.

Writing asynchronous code in .NET

Over the years there have been multiple ways to write asynchronous code in .NET with async/await being the latest attempt to make it less error-prone and more developer friendly. We started the asynchronous journey in .NET 1.0 with the Asynchronous Programming Model where you had to write a Begin and End method following a specific pattern: This was improved in .NET 2.0 with the introduction of the Event-Based Asynchronous pattern(focussing mainly on client applications) in combination with the SynchronizationContext simplifying the scheduling of work on the UI thread: In .NET 4.0 the System.Threading.Tasks.Task type was introduced, a data structure that represents the eventual completion of some asynchronous operation: And finally we arrived at async/await where we use the power of iterators to generate a state machine that handles all the continuations and callbacks for us. This allows us to write asynchronous code in a way that almost feel as synchronous simplifying...

An alternative approach to structuring your tests in XUnit

I typically write my unit tests using the AAA(Arrange-Act-Assert) pattern. This pattern splits a test in 3 sections: The Arrange section of a unit test method initializes objects and sets the value of the data that is passed to the method under test. The Act section invokes the method under test with the arranged parameters. The Assert section verifies that the action of the method under test behaves as expected. Here is an example from one of my projects using XUnit : In the example above you can see that I include the 3 sections of the AAA pattern inside the test method itself. Recently I was reading a blog post by Jeremy Miller where I noticed he was using a different approach to separate the 3 sections: In the example above, Jeremy is using the IAsyncLifetime feature of XUnit to split the 3 sections: This also works when you don't need async logic by using the constructor and the regular IDisposable interface: What I like about this approach is...

Progressive Web App–Icon is not loaded

Progressive Web Apps (PWAs) are web apps that use service workers , manifests , and other web-platform features in combination with progressive enhancement to give users an experience on par with native apps. An important building block in transforming your web application into a PWA is the web application manifest . This is a JSON text file that provides information about a web application that the browser needs to install your PWA on a device, such as the app's name and icon. For one of our PWA’s we noticed that the image icon was not loaded. In the browser console, we noticed the following error message: If we take a look at the manifest file itself, it looks OK: And the used image is available in a subfolder relative to the manifest file: What turns out to be the problem is that our application is running in a virtual directory, e.g. https://example.com/application/ . Although the manifest.json file is hosted at that path, the browser tries to load the images f...

Using IAsyncEnumerable with Dapper

When using IEnumerable in asynchronous context, you could not await it. With the introduction of IAsyncEnumerable it becomes possible to asynchronously iterate over a sequence of elements. It allows you to use the await keyword within the loop, which means you can perform asynchronous operations on each element as you iterate over them. In other words, IAsyncEnumerable provides an asynchronous version of the IEnumerable interface, making it easier to work with asynchronous data streams. You can use it to represent data streams that are produced asynchronously, such as a stream of data received over a network or a series of results returned from an asynchronous database query. I was wondering if I could use this interface with Dapper , the open source micro-ORM for .NET. It turned out that there was no IAsyncEnumerable   support available out-of-the-box but maybe we could (easily) add it ourselves? I created the following extension method: Here is an example on how to ...

Lehman’s Laws of Software Evolution

In the world of software engineering, the Lehman's Laws of Software Evolution are widely recognized as a fundamental framework for understanding how software systems evolve over time. These laws were introduced by British computer scientist, Meir Lehman, in the 1980s(!) in his paper “Programs, Life Cycles, and Laws of Software Evolution”, and they remain relevant to this day. Lehman's Laws describe how software systems evolve and how they can be managed over their lifespan. In this blog post, we will explore these laws in detail and their significance in software development. From the paper : The first law of software evolution states that software systems must evolve or they will become progressively less useful . This law recognizes that software is not static and unchanging, but instead must adapt and grow to meet changing user needs and technological advancements. Failure to evolve software systems can result in decreased usefulness or even obsolescence. This means...

ASP.NET Core–Factory based vs Convention based middleware

Today I had to create my own ASP.NET Core middleware. I forgot how to exactly do this but I noticed that an IMiddleware interface existed. I wasn't aware of this interface which brought me to the discovery that there in fact multiple ways to define and create middleware in ASP.NET Core. Let’s explain each one of them and discuss the differences. Inline middleware The simplest solution is to use an inline request delegate: This is a great way for simple use cases but once your middleware gets more complex it is time to move to one of the 2 other approaches. Convention based middleware The convention based middleware is the one I was aware of that it existed and that I had used before. To use the convention based middleware you create a separate class that follows these rules: It has a public constructor with a parameter of type RequestDelegate . It contains a public method named Invoke or InvokeAsync . This method must: Return a Task . Ac...

How Microsoft is using GraphQL in their new Teams architecture

Microsoft has made a significant investment in the re-architecture of its Microsoft teams desktop client, which is available in preview at the moment of writing this post. Although there are a lot of great improvements in the new Teams I want to focus on the new technical architecture which they shared in this post: Microsoft Teams: Advantages of the new architecture . What I found really interesting is how they brought GraphQL into the mix: If you look at the schema above, notice the Client Data Layer on the right. This layer is hosted inside a Web Worker and used to overcome the single-threaded nature of JavaScript. It enables functionality like data fetch, data storage, push notifications, and offline functionality(through Index DB) and all this running on parallel threads. The Teams window(using WebView2 ) is abstracted from the client data layer through GraphQL. I think this is a use case where I wouldn’t have thought about this technology myself but it is a great examp...

HotChocolate GraphQL–Include Exception details

By default the HotChocolate GraphQL server does not expose any exception details when an errors occurs. The only information you get back is the following: This is of course a good idea from a security endpoint but not very helpful when you want to investigate a problem. In order to automatically add exception details to your GraphQL error you can switch the execution option to include exception details: Remark: When a debugger is attached this behavior is changed automatically and exception details are included. More information: Error Filter - Hot Chocolate - ChilliCream GraphQL Platform

Disable TypeScript compilation in Visual Studio

I have an ASP.NET Core application with a corresponding Angular app. For convenience I host the Angular app as a part of the ASP.NET Core application. So I have the Angular TypeScript files as part of my solution: When I run the Angular build the output is copied to the wwwroot folder of the ASP.NET Core application: However by including the TypeScript files as part of my solution Visual Studio tries to compile my Angular application when I run a build. In this case this is not what I want as it resulted in the following errors: To fix it, I had to disable TypeScript compilaton. This can be done by adding the TypeScriptCompileBlocked property to your project file and set this to True :

The pursuit of happiness

No, this is not a post about the film with Will Smith from 2006. (Never have seen the film, so couldn't share my opinion about it). Instead I want to talk about something else. Image generated by Dall-E In my current professional role, I have the privilege of working with numerous young individuals. Specifically, individuals born after 1990, often referred to as Generation Z. If I had to describe this generation in one word, it would be “FOMO” or the fear of missing out . This generation holds high expectations for their lives, seeking an interesting career, a high salary, engaging hobbies, parenthood, travel, and more. In essence, they possess a lengthy bucket list, extensive enough to last four lifetimes (if one were to believe in reincarnation). While I admire their enthusiasm and eagerness towards life, it can also lead to a significant pitfall: a life-long pursuit of happiness. Whenever I have the opportunity, I like to share with them the secret equation for happiness...

Visual Studio–Generate C# client for OpenAPI

There are multiple ways to generate a C# client based on an OpenAPI specification file. Today I want to show you how this can be done directly inside Visual Studio. To import an OpenAPI reference, you can right-click on your project and choose Add –> Service Reference : Choose OpenAPI from the list of possible service references and click on Next: Now we can specify the details to our OpenAPI JSON file. Click on Finish to generate the client: It can take some time to generate the client. So be patient. What is happening behind the scenes? Let us have a look at all the things that Visual Studio is doing behind the scenes. First a copy of the OpenAPI json file is imported into our project and stored inside an OpenAPIs folder: On this JSON file the build action is set to Open API File Reference and specific code generation attributes are configured: Our updated csproj file looks like this: Behind the scenes the code generator is using the Microsoft....

MassTransit–Minimal Message Handlers

By default message handling in MassTransit is done through Consumers . A consumer consumes one or more message types when configured on or connected to a receive endpoint. MassTransit includes many consumer types, including consumers, sagas, saga state machines, routing slip activities, handlers, and job consumers. With the upcoming 8.1 release, an extra way to handle messages will be "Minimal Message Handlers". Instead of defining a separate Consumer class, a function is provided to handle a given message type, in the trend of the "minimal APIs" feature in ASP.NET Core. To use this feature, you need to use the AddHandler method on the IBusRegistrationConfigurator : Of course in this example there is not much happening. Let us extend the example above and log the incoming request message. To inject extra dependencies, we can specify them as extra parameters to the method: Instead of passing the message directly, we can also use the ConsumeContext to acc...

Make your ASP.NET Core application always running on IIS

By default when running an ASP.NET Core application in IIS, the application will not be started until the first user hits your ASP.NET Core application. This of course saves some resources(CPU, memory,...) when no one is accessing your site, but comes with a performance penalty when the first request arrives. A related feature exists where the application pool is shutdown after some idle time. Although I think this is a good default it is not what we want when we have one or more background tasks running in our ASP.NET Core application . In these situations you want to have your ASP.NET Core application always running. Let me walk you through the steps how to get this done. Install IIS features First check if you have the Application Initialization Module installed in IIS. If you are doing this on your local development machine, have a look at the list of Windows Features: Otherwise you can install it through Server Manager: Open the Add Roles and Features Wizard ....