Software Engineering Principles and Practices

Articles covering the principles, practices, and methodologies of professional software development – from clean code and architecture to testing, design patterns, and modern development processes.

Practical insights for developers at all levels who want to build maintainable, scalable, and high-quality software.

Six Ways ILogger Silently Fails in Production

Six Ways ILogger Silently Fails in Production

I lost half a day because BeginScope silently did nothing in production: no error, no warning, just a flat stream of undifferentiated log entries. ILogger is a façade over a pipeline full of opt-in behaviour that looks enabled by default. Scopes, structured properties, minimum levels, exception chains, timestamps: all have failure modes that compile cleanly and fail quietly.
The Code You Write Today Is Someone's Problem Tomorrow

The Code You Write Today Is Someone's Problem Tomorrow

The code you create is a valuable legacy — my author bio. Not marketing copy. It’s the most expensive lesson from nearly two decades in production systems. This article explains what it actually means when you’ve lived with the consequences.
Stop Pretending TimeProvider Doesn't Exist

Stop Pretending TimeProvider Doesn't Exist

DateTime.UtcNow looks harmless. It is not. It is a hidden dependency you cannot control in tests, cannot reproduce in staging, and cannot freeze to catch the bugs that only surface at midnight or on the last day of the month. .NET 8 shipped TimeProvider to fix this. Two years on, most codebases still ignore it. Some planned to adopt it later. Later has not arrived.
AI Code Review Is a Sycophant

AI Code Review Is a Sycophant

AI code review tools are genuinely useful for catching syntax errors, obvious bugs, and common anti-patterns. They are also systematically unable to tell you that the feature you built was the wrong call, that the abstraction is off, that the naming reveals confused thinking, or that the correct review comment is “delete this.” Here is what AI reviews find, what they miss, and why human judgment still has no substitute.
Source Generators: The Build Performance Killer Nobody Warned You About

Source Generators Hidden Costs

Source generators are powerful. They are also running on every single build, blocking IntelliSense, breaking Hot Reload, and multiplying their cost across every target framework you support. Nobody mentions this in the getting started guides. Here is how to measure the damage, find the culprits, and decide when source generators are actually worth it.
Purpose Limitation in API Design: Leaking Data You Shouldn't

Purpose Limitation in API Design: Leaking Data You Shouldn't

Most APIs expose personal data based on database entities, not caller needs. When a password reset endpoint returns a user’s full profile, purchase history, and marketing preferences, that’s purpose drift. This article shows how to restructure ASP.NET Core APIs around caller purposes using resource-based authorization, consent validation, and field-level access control.
Real Professional Software Engineering in the AI Era

Real Professional Software Engineering in the AI Era

Throughout this series, we’ve established that AI-generated code without understanding creates productivity illusions that collapse in production (Part 1), and that the feedback loop between code and reality—compilation, testing, profiling, production—sharpens thinking in ways AI can’t replicate (Part 2). Now we confront the practical question: What defines professional software engineering when code generation becomes trivial? This final part examines the irreplaceable skillset: understanding execution characteristics (recognizing allocation patterns that cause GC pressure before deployment), asking questions AI can’t formulate (What’s the failure mode when this service is unavailable?), recognizing when plausible AI solutions diverge from correct ones, debugging production failures AI has no execution model to reason about, and evaluating maintainability for code that becomes tomorrow’s burden. We explore why prompt engineering optimizes for speed while architecture optimizes for survival, why “AI productivity” often means faster technical debt accumulation, and why the economic reality favors organizations that measure system reliability over lines of code generated. The feedback loop can’t be automated because closing it requires learning from production failures and applying that knowledge to prevent future ones—the irreplaceable discipline that defines real professionals in 2026 and beyond.
The Feedback Loop That AI Can't Replace

The Feedback Loop That AI Can't Replace

In the first part of this series, we established that AI-generated code without understanding creates an illusion of productivity that collapses under production load. The differentiator isn’t typing speed—it’s the feedback loop where code meets reality and exposes incomplete thinking. But what exactly is this feedback loop, and why can’t AI replicate it? Modern compilers validate logical consistency, catching gaps pure thought leaves unresolved. Profilers expose the 75x performance difference between “seems reasonable” and “actually performs.” Production environments reveal every assumption abstract thinking deferred—scale, concurrency, failure modes. This article explores the mechanisms that transform vague reasoning into concrete understanding: compilation validates logic instantly, testing catches behavioral mismatches, profiling measures what abstract analysis guesses, and production exposes the cost of every deferred decision. Real professionals don’t just write code—they master the iterative discipline of watching it fail, understanding why, and refining their thinking. AI participates in parts of this loop, but it can’t close it. That’s where professionals remain irreplaceable.
Kehrwoche: What Swabian Cleaning Teaches About Technical Debt

Kehrwoche: What Swabian Cleaning Teaches About Technical Debt

Kehrwoche—a Swabian cleaning tradition—is scarier than breaking the build on Friday afternoon. At least the build doesn’t remember next Tuesday. Mrs. Schmid from the second floor does, and she remembers well. What does a weekly cleaning schedule in southern Germany have to do with technical debt? More than most software teams want to admit.
Alphabet Soup: The Format Buffet Nobody Ordered

Format Buffet Nobody Ordered

Developers wanted one format. We got twenty. CSV mangles data, XML drowns in tags, JSON forbids comments, YAML punishes spaces. TOML tried fixing it. TAML went minimal. TOON optimized for AI. CCL brought category theory. Result? Five formats per project, three parsers, and debugging why NO became false. AI can’t save us either. Welcome to format hell.
Why Real Professionals Will Never Be Replaced by AI

Why Real Professionals Will Never Be Replaced by AI

The elephant everyone ignores: AI can generate code faster than you can type. GitHub Copilot autocompletes entire functions. ChatGPT builds APIs from prompts. Typing is dead. So why will real professionals never be replaced? Because “vibe coding”—describe what you want, ship what AI generates—is a productivity illusion that collapses spectacularly in production. When code generation becomes trivial, understanding what that code costs, where it fails, why it breaks under load becomes everything. AI generates syntax. Professionals understand execution, failure modes, operational cost, and production consequences. The differentiator isn’t typing speed—it’s mastering the feedback loop: write code, watch it fail, understand why, refine thinking. This discipline can’t be automated. Prompt engineers generate code. Real professionals ensure it survives contact with reality.
Most Software Teams Are Lying to Themselves—2026 Needs to Be Different

Most Software Teams Are Lying to Themselves—2026 Needs to Be Different

Happy New Year 2026! 🎉

Fix one piece of technical debt this week—not next quarter. .NET 10, analyzers, and tests are ready; discipline is the only missing part.