Friday, May 7, 2021

Tools and resources for Agile forecasting

As a developer or teach lead sooner or later you will be asked to estimate. Of course you could just throw out a ballpark figure but better is to use some historical data about your team performance.

In that case I would recommend having a look at the online calculators and forecasting spreadsheets created by Focused Objective. They provide a lot of tools but also articles that can help you answer different questions about the current and future performance of your team.

Thursday, May 6, 2021

Docker diff

When investigating a problem with a docker file I wanted to check what was changed when running the docker image.

I first had to lookup the container id through docker ps:

C:\Users\bawu>docker ps
CONTAINER ID   IMAGE                         
2ca085df3487   masstransit/rabbitmq:latest
 

Now I could ran docker diff <CONTAINER> using the container ID  to see the files that are changed: :

C:\Users\bawu>docker diff 2ca085df3487
C /var
C /var/log
C /var/log/rabbitmq
A /var/log/rabbitmq/log
A /var/log/rabbitmq/log/crash.log
C /etc
C /etc/rabbitmq
A /etc/rabbitmq/rabbitmq.conf

Wednesday, May 5, 2021

Build your ASP.NET Core application outside the Docker container

Most of the examples you find when using an ASP.NET Core application inside a Docker container use the multistaged build approach.

In this approach you create a dockerfile where building the application happens inside the docker file, the output of this build will then be used in a second stage to create the final docker image:

This is fine and results in small optimized docker images. So why this blog post?

The problem becomes clear when you take a look at our build pipeline:

What you can see is that we build the application twice; one time to run the unit tests, code analysis, vulnerability scanning etc… and one time to produce the docker image. Although we use different stages in Azure pipelines, it is still a waste of resources.

An alternative approach is to build your ASP.NET Core application outside the Docker container. The dockerfile is only used to copy the build artifacts from the publish folder into the docker image.

More information: https://docs.microsoft.com/en-us/dotnet/core/docker/build-container?tabs=windows#create-the-dockerfile

Tuesday, May 4, 2021

C# 9 Switch Expressions with Type patterns

C# 9 allows you to combine the power of pattern matching with switch expressions.

I had a use case where I had to check the type of an object and depending on the type execute different logic.

Before C# 7 type checks where not possible, so although I wanted to write the following switch statement, this would not compile:

In C#7 Type pattern support was added so then I could write the following

C#9 further improves this by the introduction of switch expressions. Now I could handle this use case like this:

Neat!

Monday, May 3, 2021

Azure DevOps Pipelines - The OutputPath property is not set for project

When trying to build a csproj file using Azure DevOps pipelines, it failed with the following error message:

The OutputPath property is not set for project

The important thing to notice here is that this only happens when pointing the build task to a csproj file instead of a sln file.

Turns out that there is a small difference between how the platform variable is configured at the solution level vs the project level.

These are the variable settings we use inside the build task:

  • $(BuildConfiguration)= “Release”
  • $(BuildPlatform)=”Any CPU”

When I took a look at the csproj file it was expecting “AnyCPU” as the platform setting not “Any CPU”. (Notice the space)

I fixed it by setting the BuildPlatform to “AnyCPU” and not use the build variable for this specific task.

Friday, April 30, 2021

Architecture Weekly

Interested in software architecture?

I discovered ‘Architecture Weekly’, a weekly list of links so you know what to read during the weekend.

Thursday, April 29, 2021

C#–Hide a base class for usage outside an assembly

I created an abstract base class in C# but didn’t want it to be used outside the assembly I created it in.

How can you achieve this?

Your first guess could be to change the access modifier of the base class to internal. When you try to do this you’ll get the following error message:

Inconsistent accessibility: base class 'MyBaseClass' is less accessible than class 'MyInheritedClass'

You have no other choice than to make the abstract class public what makes it visible outside the assembly.

Is there still a way to only allow classes in the same assembly to implement it?

The trick is to make the abstract base class public, but give it an internal default constructor:

This will allow MyBaseClass to be visible outside the assembly, but classes outside the assembly cannot inherit from it.