Skip to main content

Posts

Showing posts from April, 2023

Azure DevOps– Clean the work directory of your build agent

In Azure Pipelines when you use the classic task based pipeline, you can use the Clean option to clean up the working directory of your private agent before the build is run. You can find this setting by clicking on the Get Sources section in the pipeline editor. If you set this option to True you can choose what you exactly want to clean up: Using this option has a clear performance impact but can be useful in situations where the build is showing strange behavior. YAML pipelines But what if you are using YAML pipelines? When using YAML pipelines,  you can achieve the same goal by configuring the workspace clean option on the job: When you specify one of the clean options, they are interpreted as follows: outputs : Delete Build.BinariesDirectory before running a new job. resources : Delete Build.SourcesDirectory before running a new job. all : Delete the entire Pipeline.Workspace directory before running a new job. It is also possible to use

AKS–The single biggest reason why you should apply a GitOps approach

GitOps is an approach to software delivery that uses Git as a single source of truth for declarative infrastructure and application deployment. With GitOps, all changes to infrastructure and applications are made through pull requests that are reviewed and approved before they are applied to the target environment. This approach offers several benefits, including improved visibility, traceability, but the single biggest reason why you should apply a GitOps approach is (enhanced) security compared to a traditional Continuous Delivery approach. Flux In Azure you can use GitOps in Azure Kubernetes Service (AKS) and Azure Arc-enabled Kubernetes clusters.Behind the scenes this uses Flux , a popular open-source tool set. Flux provides support for common file sources (Git and Helm repositories, Buckets, Azure Blob Storage) and template types (YAML, Helm, and Kustomize). GitOps vs traditional Continuous Delivery(CD) In a traditional CD setup, the CD tooling is running outside the AK

Javascript–Using splice instead of delete

I have to admit that the amount of Javascript code I write is really limited. And even then I use TypeScript most of the time. Anyway this is only a disclaimer because maybe I'm stating something that is obvious to you. It certainly wasn't to me :-)! I had a really simple use case to solve: I needed to delete a specific item from an array .I didn’t know the exact function name anymore so I asked Google and got back with the delete operator . This turns out to the wrong approach as the delete operation will delete a property from an object and set it to undefined: The correct way is to use the splice function : I hope I never forget it anymore!

ASP.NET Core Guidance

When building scalable server applications using ASP.NET Core, there are common pitfalls that should be avoided and some (best) practices that can help you along the way. Last week I was watching the NDC recording of Damian Edwards and David Fowler talk Why your ASP.NET Core application won’t scal e: In this presentation they share a lot of interesting insides in how to built better performing ASP.NET Core applications. During this talk they point to this Github repo from David Fowler: davidfowl/AspNetCoreDiagnosticScenarios The goal of this repository is to show problematic application patterns for ASP.NET Core applications and a walk through on how to solve those issues. At the moment of writing it contains 2 guides with related code examples General ASP.NET Core Asynchronous Programming A must read for every developer who wants to build scalable ASP.NET Core applications!

Applying the decorator pattern in .NET Core using Castle.DynamicProxy

In this post I want to explain what the decorator pattern is, why it is useful and how you can implement it in a generic way using Castle.DynamicProxy. What is the Decorator pattern? Before we dive into the technical details, let us start with a recap about what the decorator pattern actually is: Decorator is a structural design pattern that lets you attach new behaviors to objects by placing these objects inside special wrapper objects that contain the behaviors. There are a lot of use cases where the decorator pattern can help, in this blog post I focus on one of them; using a decorator to handle cross cutting concerns(caching, error handling, logging, …) without polluting your original object. I’ll show you an example where I introduce caching at the repository interface level. How to integrate the decorator pattern in a generic way? You don’t need a special library or anything to implement the decorator pattern in C#. However I would like to write it in a gener

AutoMapper issue after upgrading to .NET 7

While upgrading a .NET Core 5 application to .NET 7 I encountered the following issue; when I tried to run the application it failed with the following error message: Method System.Linq.Enumerable.MaxFloat: type argument 'System.Int32' violates the constraint of type parameter 'T'. And for completeness, the full stack trace: at System.RuntimeType.ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception e) at System.Reflection.RuntimeMethodInfo.MakeGenericMethod(Type[] methodInstantiation) at AutoMapper.Internal.TypeDetails.<>c__DisplayClass25_1.b__10(MethodInfo extensionMethod) at System.Linq.Enumerable.WhereSelectArrayIterator 2.MoveNext() at System.Linq.Enumerable.ConcatIterator 1.MoveNext() at System.Linq.Enumerable.d__231 3.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator 2.MoveNext() at System.Linq.Enumerable.UnionIterator 1.MoveNext() at System.Linq.Enumerable.ConcatIterator 1.MoveNext() at AutoM

Encapsulate libraries not frameworks

Encapsulation is a way of organizing code into separate modules, where each module has a clear and well-defined responsibility. It allows for better code reusability, maintainability, and testability. Libraries and frameworks are both useful tools for building software applications. However, there is a key difference between the two in terms of encapsulation. Libraries are typically designed to provide a set of functions or utilities that can be used in a variety of contexts. They are generally more loosely coupled and have fewer dependencies on your application code. Encapsulating a library means that you isolate its functionality and implementation details, allowing your application code to interact with it through a well-defined interface. It can be a good idea to encapsulate a library to limit the dependencies to third-party components which makes it harder to maintain your application in the long run. Typically we do this by creating a wrapper that isolates our component by

Upgrading to .NET 6 -ASP0014 warning

In preparation of a GraphQL workshop I'm giving later this week, I was updating my demos to .NET 7. The original demos were written in .NET 5, but with the introduction of minimal API's in .NET 6 I decided to take that route. So I removed my Startup.cs file and copied everything inside my Program.cs file: This however resulted in the following error message(which is in fact a warning but I have 'Treat Warnings as Errors' enabled in Visual Studio): ASP0014: Suggest using top level route registrations In .NET 6 routes no longer need to be nested inside an UseEndpoints call, so I can rewrite the code above to get rid of this warning: More information: ASP0014: Suggest using top level route registrations | Microsoft Learn

InvalidOperationException: Cannot resolve from root provider because it requires scoped service

A colleague contacted me with a specific error she got. The strange thing was that the error never appeared during local development but only after deploying the application to our Development environment. Let's first have a look at the error message: The error happens during the bootstrapping of the application. For me it was immediately clear what the problem was but if you don’t spot the root cause, no worries. I’ll show you the related code, maybe that helps. First here is the specific Serilog enricher: And here is the bootstrapping code: The problem occurs when we resolve the ILogger singleton instance. When we do this a transient enricher is used that injects a scoped IUserFactory. As there is no scope available at that moment, this leads to the error above. To fix it, we have to change the lifetime of our IUserFactory to transient: > Than the question remains: Why this error doesn’t happen during local development? The answer is Scope Validation

Upgrading to HotChocolate 13 - There was no argument with the name `…` found on the field `…`.

I spent some time trying to upgrade the HotChocolate workshop from version 11 to 13. If you are interested in the end result, check out my blog post here . Most things still worked and a few things were marked as obsolete and easy to replace. However there was also some stuff that was less obvious. One error I got was when I tried to fetch a related object through a resolver. Here is the GraphQL query I tried to execute: And here is the error I got: Let’s have a look at the resolver we were using: And here is how it is used: A look at the migration docs explained the problem.Starting from HotChocolate 12 the ParentAttribute is required when a resolver argument is referring to the parent object. So to fix the problem we have to update our resolver and introduce the ParentAttribute :

Your most important skill as an architect

As an architect, the foremost important skill is ... empathy . It is the ability to perceive and comprehend things from the perspective of others, empathize with their emotions and feelings, and envision oneself in their position. We live in a world where things are reduced to two camps, its us vs them. Where in fact if you take the effort to bridge the distance, you’ll see that there is more that unites us than that separates us from each other. But therefore you need to be willing to take the first step and that requires courage and empathy. The IT industry is not different from the ‘real’ world with its own dichotomy of business versus IT. And unfortunately it always seems that these 2 camps are on a collision course, especially when things are not going as planned. As an architect, I am continually navigating between these two "camps" or as Gregor Hophe would phrase it, I’m riding the ‘architecture elevator’. Empathy is the key to success in this profession, as it

Strawberry Shake–Access to the path ‘obj\\berry’ is denied

When trying to build a C# project in Visual Studio 2022 v17.5, I got compiler errors. This was strange because the only thing that has changed was the Visual Studio version.  Here is the exact error I got: In this project I was using the Strawberry Shake GraphQL client . This client uses a custom GraphQL compiler build action and it was exactly this step that failed. The quick fix Let me first explain a quick fix. This problem is indeed related to the Visual Studio version which seems to became more strict on what is allowed and what not.  To get rid of the error, restart your Visual Studio instance and run it under Administrator privileges. Updating to Strawberry Shake 13 Unfortunately before I arrived at the quick fix above I took the long path and started an update to Strawberry Shake v13. This turned to be more work than I had expected. Let me walk you through the steps: Remove the package references to StrawberryShake.CodeGeneration.CSharp.Analyzers and Strawb

HotChocolate 13– Updated workshop

I'm a big fan of GraphQL and HotChocolate is the GraphQL server of my choice when building .NET applications. If you are new to HotChocolate I can recommend having a look at the workshop that is available on their Github . Unfortunately this workshop is still for .NET 5.0 and HotChocolate 11. I'm working on porting the workshop to HotChocolate 13, the latest version on the moment of writing this post. If you want to checkout this version, you can find my fork here: https://github.com/wullemsb/graphql-workshop Remark: I have planned to provide the updated version as a pull request once I’ve ported everything.

Design your graph models using Arrows.app

Quick tip for you today if you are looking for a tool to help you draw your graph models. Have a look at arrows.app . Arrows.app is a free tool created by the Neo4j team offering the following features: Quick Intuitive drawing with a mouse. Neo4j Property Graph Model Draw: nodes, relationships, properties, labels. Fine-grained Styling Control: sizes, layouts, colors. Export as image or Cypher Use images in documents or presentations. Run Cypher to create graphs in Neo4j. I especially like the last feature as it makes it very easy to translate your model to a real graph in Neo4j: To learn more about the tool, check out the following Youtube video:

Versioning in graph databases

I got a question from one of my teams last week on how to apply versioning in Graph databases. There are multiple ways to tackle this problem but let me share the way I typically handle this. What do you mean with ‘versioning’? Let me start by explaining what I mean exactly with ‘versioning’.  Our data changes over time. Without versioning we only now the current state of our data but not what happened in the past. By applying versioning techniques, we can keep track of changes both on the data and its dependencies. This can be useful for auditing purposes but there are a lot more reasons why this can be applied. There are multiple types of versioning but the question I got was related to time-based versioning. The idea with time-based versioning is that you can track changes over time. We end up with an append-only model where we are able to step through time to understand the state changes. How to model time-based versioning in graph databases? The core idea with time-based