Friday, October 30, 2020

Azure DevOps Docker build error–No such file or directory

When trying to build a new .NET core project using Azure DevOps it failed with the following error message:

Step 6/16 : COPY ["DockerWebApplication1/DockerWebApplication1.csproj", "DockerWebApplication1/"]
COPY failed: stat /var/lib/docker/tmp/docker-builder590338138/DockerWebApplication1/DockerWebApplication1.csproj: no such file or directory
##[error]COPY failed: stat /var/lib/docker/tmp/docker-builder590338138/DockerWebApplication1/DockerWebApplication1.csproj: no such file or director
The problem is that the COPY command is using the wrong folder to COPY from. To fix it, update your Docker Build task:
  • Uncheck the “Use Default Build Context” checkbox
  • Set  the “Build Context” field to "$(System.DefaultWorkingDirectory)"

Thursday, October 29, 2020

Software development is learning

In every software project you have 2 sides: the problem space and the solution space. The problem space is typically owned by a product owner, he or she knows the problem they want to solve. The solution space is owned by the developers, they know how to solve those problems.

Easy right? Unfortunately it isn’t so easy as it sound. Product owners don’t always succeed in explaining the problem (or describe a workaround instead of the real problem). As a result, developers don’t always get it right the first time and build the wrong solution.

The most important lesson you can take with you on any software project is that is all about learning. As you are learning nobody expects that you get it right from the first time. Instead somebody points you your mistakes and gives you feedback.

So how can we become better in writing software? Not by typing faster and certainly not by making no mistakes.

We become better by having better feedback faster. The key is shorter feedback loops; the compiler who tells you you’ve made a mistake, a smoke test that immediately warns you that there is a problem with a build, a user that gives feedback when you demonstrate a new feature, …

Wednesday, October 28, 2020

Tuesday, October 27, 2020

HotChocolate - Apollo Tracing

To investigate what’s going on inside your GraphQL backend I would recommend to enable Apollo tracing. You can always enable this but as this has a (small) performance impact, a better way is to enable it on demand.

In HotChocolate you can specify this through the QueryExecutionOptions:

After doing that, tracing will be activated when ad GraphQL-Tracing HTTP header with a value of 1 is added to the request.

Now your GraphQL result will not only contain the data but also tracing information. GraphQL tools like GraphQL Playground can visualize this data:

If the tracing information is not shown, check your GraphQL Playground settings and see if "tracing.hideTracingResponse" is set to false.

Monday, October 26, 2020

SonarCloud–New Code Definition

When scanning a project for the first time through SonarCloud in your Azure DevOps build pipeline, a new SonarCloud project is created automatically.

The second time your build runs a comparison is done and you’ll have your first Quality Gate results. At least that is the theory…

When we tried to do this for a new project, the corresponding SonarCloud project was created. However we got the following warning when browsing to this project in SonarCloud:

This is a new requirement for every SonarCloud project to specify how ‘new code’ is identified. You can choose between the following options:

  • Previous version: All code that has changed since the previous version
  • Number of days: All code that has changed in the last x days
  • Specific date: All code that has changed since the specified date

It can be set in the organization settings(Organization –> Administration –> New Code) and applies to all new projects.

Unfortunately setting this didn’t resolve the issue for this already existing project. I couldn’t find a way to get rid of the error so in the end I solved it by throwing away and recreating the project.

Friday, October 23, 2020

Learning Docker in a month

If you are new to Docker, I can recommend the Learn Docker in a Month of Lunches YouTube series.

It will cost you your lunch break but that is a small cost to pay…

Thursday, October 22, 2020

Azure DevOps - Allow users to edit process templates

I got the following question from a colleague;

“Is it possible to give all team members the necessary rights to edit a specific process template?”

Let’s see how we can do this:

  • Scroll to the Process section on the left and click on it.

  • Click on the next to the Process template you want to use and click on the Security Item in the context menu.

  • Search for the team you want to add. After adding it, change the Edit process permission to “Allow”.

  • That’s it!

Wednesday, October 21, 2020

Entity Framework Core –Pessimistic concurrency

After blogging about pessimistic concurrency and the usage of locks in NHibernate yesterday, I wanted to write a follow up on how to do the same thing in Entity Framework Core.  Turns out that EF Core does not support Pessimistic Concurrency…

However this does not mean it is not possible. We’ll have to throw some raw SQL in the mix to get it working.

First we need to explicitly create a database transaction:

After doing that we need to set the lock. We do this by creating a ‘fake’ update statement with a lock statement:

Now we can execute our ‘real’ update using EF Core:

Here is the full code example:

DDD–Strongly typed Ids

One of the core principles of DDD is the usage of value objects to avoid “primitive obsession”. "Primitives" refer to the built-in types in C#,  int, string,guid etc. "Primitive obsession" refers to over-using these types to represent domain concepts that aren't a perfect fit. Some examples are a HouseNumber that is represented by an int or an EmailAddress that is represented by a string.

This concept not only makes sense for your value objects but is also valuable for your Entity and AggregateRoot id’s. A ProductId should not be interchangeable with an OrderId.

Creating a valueobject for every Id type is not that hard but remains cumbersome. Let’s introduce StronglyTypedId as a solution.

From the website:

StronglyTypedId makes creating strongly-typed IDs as easy as adding an attribute! No more accidentally passing arguments in the wrong order to methods - StronglyTypedId uses Roslyn-powered build-time code generation to generate the boilerplate required to use strongly-typed IDs.

Getting started

  • To get started, first add the StronglyTypedId nuget package to your project: https://www.nuget.org/packages/StronglyTypedId/
  • Now create a struct type and add the StronglyTypedId attribute on it.
    • Notice that we specify to not generate a JsonConverter. If you want to serialize the type you need to add an extra reference to Newtonsoft.Json or System.Text.Json.
  • Build your project. Let’s have a look at what is generated:
  • By default a Guid is used as the backing field. If you want to use a different type, you can specify this:

Tuesday, October 20, 2020

NHibernate–Pessimistic concurrency

In most cases locking is something that you want to avoid as it limits the level of concurrency of your database. But sometimes that is exactly what you want.

You can use pessimistic concurrency in NHibernate by using an overload that takes a LockMode:

When using session.Get<T>:

Or when using session.Query<T>:

Microsoft MakeCode

If you want to learn your children the joy of programming, have a look at Microsoft MakeCode.

From the website:

Microsoft MakeCode is a free, open source platform for creating engaging computer science learning experiences that support a progression path into real-world programming.

It contains a lot of simulators, tutorials and examples for multiple devices and platforms.

Monday, October 19, 2020

Azure DevOps– Lead time and cycle time

Both lead time and cycle time can be measured and visualized in Azure DevOps.

Lead time is calculated from work item creation to entering a completed state. Cycle time is calculated from first entering an In Progress state to entering a Completed state as visualized below:

The easiest way to get this data is by using the Cycle Time and Lead Time widgets.

  • To enable these widgets, go to the Dashboards page in your Azure DevOps project.

  • Click on Edit on the right.
  • In the Add Widget search box, enter ‘cycle’ to search for the Cycle Time widget. Click on Add to add it to the dashboard

  • On the Configuration page, you can select the team, backlog level and time period. You also have the option to further filter the backlog using field criteria.

  • Click on Save and Close to apply the configuration.

  • Repeat the steps above for the Lead Time widget.

More information: https://docs.microsoft.com/en-us/azure/devops/report/dashboards/cycle-time-and-lead-time?view=azure-devops

HotChocolate GraphQL - Integration test authorization

The HotChocolate blog gives some guidance on how to write integration tests. This is a good starting point but doesn’t help you get to a final solution when you are using authorization in your GraphQL schema.

In that case you need a way to inject an authenticated ClaimsPrincipal into the GraphQL middleware. It took us some time to figure out a solution but here are the steps involved:

Create custom middleware:

Register middleware:

Friday, October 9, 2020

GraphQL Altair–Test and debug your GraphQL queries

As the GraphQL ecosystem keeps growing I’m continually founding new tools that make my job as a GraphQL developer easier. Recently I started using Altair, a GraphQL client application that makes it easy to test your GraphQL endpoints.

A selection of the features it has to offer:

  • Multi language/platform/window
  • Import and export queries
  • File upload
  • Syntax and query highlighting
  • Autofill all fields

Thursday, October 8, 2020

Quick tip if you want to play around with C# 9

The easiest way to start playing with C# 9 is by installing LinqPad 6. This allows you to play with the new language features without installing any extra dependencies.

To enable the new language features, go to Edit –> Preferences.

Go to the Query tab and set a checkbox next to Enable C# 9 preview features:

Wednesday, October 7, 2020

C#9- Record types

One of the most anticipated features coming in C#9 are Record types. Record types make it easy to create immutable reference types in .NET. They become the perfect fit for Value Objects in DDD terms.

A new keyword is introduced to support this: record. The record keyword makes an object immutable and behave like a value type.

An example:

You can even write this using a shorter syntax using positional records:

But what if you want to change the person name? How can we do this knowing that the object is immutable? Do I need to copy all properties into a new object?

Let’s introduce the with keyword to fix this. It allows you create an object from another by specifying what property changes:

Tuesday, October 6, 2020

C#9–Covariant return types

C# 9 adds a whole list of new language features. Most people talk about the support for record types and improved pattern matching but one of the features I’m happy that is finally added to the language are covariant return types.

You are probably asking covariant return what?????

Let’s explain; with return type covariance, you can override a base class method that has a less-specific type with one that returns a more specific type.

An example, before C#9 you would have to return the base type from the inherited class:

In C# 9, you can do the following:

Monday, October 5, 2020

RabbitMQ–Lazy queues

By default RabbitMQ tries to keep your whole queue in memory. This is OK as long as your messages are processed fast enough but not if your queue becomes very long(many millions of messages). Queues can become very long for various reasons:

  • consumers are offline / have crashed / are down for maintenance
  • there is a sudden message ingress spike, producers are outpacing consumers
  • consumers are slower than normal

Lazy Queues can help in these situations- messaged are moved to disk as early as practically possible, and are only loaded in RAM when requested by consumers.This comes at a cost of increased disk I/O.

You can configure this in MassTransit when configuring your receive endpoint:

More information: https://www.rabbitmq.com/lazy-queues.html

Friday, October 2, 2020

Database profiling in Visual Studio

Visual Studio 2019 version 16.3 extends the Performance Profiler with a new ‘Database’ option.  This will enable the new Database tool that captures all database activity during your profiling session.

Remark: The database tool works with .NET Core projects  using either ADO.NET or Entity Framework Core. It also works on traces collected using dotnet trace which means we can collect data anywhere that .NET Core runs (including Linux!) and analyze that data in Visual Studio.

Let’s try it:

  • Open the Performance Profiler in Visual Studio by clicking Debug > Performance Profiler.
  • Select the checkbox next to “Database” to enable the tool.

  • Click on Start to start the profiling session. Now interact with your application in the ways you’re interested in investigating. When you are done click ‘Stop collection’.

  • Now you get a table of all the queries that happened during your profiling session along with a graph that shows when and how many queries happen over time.

  • After identifying a query that warrants further investigation, you can go to the related code by right-clicking on a row, and selecting “Go To Source File”!

Thursday, October 1, 2020

Improve the startup time of your .NET Core application

Starting from .NET Core 3.x tiered compilation is enabled by default. This allows you to use precompiled code from assemblies created using the ReadyRoRun(R2R format. R2R is a form of ahead-of-time (AOT) compilation.

It improves startup performance by reducing the amount of work the just-in-time (JIT) compiler needs to do as your application loads.

To use this feature you need to enable ReadyToRun and publish your application as a self-contained app.

  1. Add the <PublishReadyToRun> setting to your project:

    <PropertyGroup>  
       <PublishReadyToRun>true</PublishReadyToRun>
    </PropertyGroup>

  2. Publish a self-contained app. Here is an example targetting the Linux ARM64 runtime:

    dotnet publish -c Release –r linux-arm64 --self-contained