Martin Stühmer

Hello there, I’m Martin, software architect and developer from the Cologne/Bonn area. Right from the start of my professional career, I decided in favor of .NET and Microsoft technologies and tools and have always incorporated them into my work. With more than 15 years of experience in the field of software architecture and development with .NET, my focus is particularly on increasing the quality and performance of development teams, the interaction of the software solution with the target environment and the actual application down to the last byte.

In my position as Director Consulting Services @ CGI, I act as enterprise architect and developer for cloud native and .NET solutions. I am also a trainer for cloud and software architecture. In addition to my professional life, I am involved in the open source communities and currently provide them with various NuGet packages with different focuses and functionalities.

A strong willingness to learn and develop is also part of my everyday life. This was taken to a new level for me in 2021 after I successfully completed my IHK trainer and my Microsoft certified trainer this year. In addition, I was able to qualify as a trainer for CGI’s Risk and Cost Driven Architecture program in 2022.

Published blogs

Stop Breaking Multi-Targeting Builds with String Comparisons

Stop Breaking Multi-Targeting Builds with String Comparisons

Last month, I watched a senior developer spend three days debugging a build failure that worked perfectly on his machine. The CI pipeline? Failed every single time. Different error messages. Inconsistent behavior. Pure chaos.

The root cause? A single line in a .csproj file:

<PropertyGroup Condition="'$(TargetFramework)' == 'net8.0'">

That’s it. One innocent-looking string comparison brought a multi-targeting .NET project to its knees.

Here’s what nobody tells you about TargetFramework conditions: string comparisons are a trap. They work on your machine because you’re building net8.0 exactly. They fail in CI because your pipeline builds net8.0-windows. They explode in production when someone adds net8.0-android six months later. And the worst part? The failures are silent. No exceptions. No obvious errors. Just conditions that stop matching and features that mysteriously vanish.

I’ve seen this pattern destroy three separate projects. Multi-targeting nightmares. Build configs that work by accident. Hours of debugging that could have been avoided with one single property function.

Microsoft documented TargetFramework property functions years ago, yet developers keep writing fragile string comparisons. So let me be brutally clear: if you’re using $(TargetFramework)' == 'something' conditions, you’re sitting on a time bomb.

Modern Defensive Programming in .NET — Unified Throw-Helpers and Multi-Framework Compatibility

Modern Defensive Programming in .NET — Unified Throw-Helpers and Multi-Framework Compatibility

As .NET evolves, developers face an ever-growing tension between modern language features and the need to maintain compatibility across multiple frameworks. Applications no longer run in isolated environments; they live within ecosystems that combine .NET Framework, .NET Core, and .NET 6 or later. In such an environment, reliability and maintainability become the cornerstones of sustainable development. Defensive programming — the art of protecting your software against invalid inputs and unintended states — plays a crucial role in achieving this stability.

Your Tests Are Lying — Mutation Testing in .NET

Your Tests Are Lying — Mutation Testing in .NET

It begins like many stories in software: a well-intentioned developer joining a project, determined to do things properly. You arrive at a codebase that has grown organically, perhaps even chaotically. You decide you will bring order. You set up unit testing, you configure continuous integration, you measure code coverage. You write dozens or hundreds of tests. Every public method is touched, every branch is at least executed. The dashboard lights up green. You feel, quite frankly, on top of things.

Then one day, production breaks under your watch

PackageDownload: NuGet's Forgotten Power Tool

PackageDownload: NuGet's Forgotten Power Tool

PackageDownload arrived in NuGet 4.8 to solve a niche but genuine problem: downloading packages without adding assembly references. It works. But its version syntax requirements and complete disregard for Central Package Management reveal the messy reality of platform evolution.
Configuration-First Health Checks for Modern .NET

Configuration-First Health Checks for Modern .NET

Let’s be honest: health checks are the broccoli of .NET projects. Everyone says they have them, but nobody’s excited to eat their greens. What starts as a humble SELECT 1 in a try/catch quickly explodes into a wild jungle of scripts, copy-pasted connection strings, and endpoints that only half the team remembers. Sure, it works—until it doesn’t. And when it breaks, it’s never at a good time.