Development Practice
This section contains notes on software development in practice, with emphasis on C#, .NET, application structure, testing, maintainability, and long-lived codebases.
The focus is on decisions and trade-offs that appear when systems are built, changed, extended, and maintained over time.
This section contains notes and observations from my long-lasting work with C#, .NET, and application development.
Testing Behavior Without Testing Implementation Details
A practical look at writing tests that protect meaningful behavior without freezing implementation details, so the code can be refactored and improved without creating noisy test failures.
Good tests should make important behavior harder to break. They should not make good code harder to write.Read article
Designing Failure Results That Callers Can Actually Use
A practical look at designing failure results that help callers make better decisions. The article explains why vague booleans, nulls, and generic exceptions often hide important meaning, and how small, stable result categories can make application workflows, diagnostics, and tests clearer.
A good result type should describe the outcome of the operation. It should not own every possible response to that outcome.Read article
Extracting a Small Provider-Agnostic Mailing Library
A practical reflection on extracting a small provider-agnostic mailing library that separates application intent from delivery mechanism. The article shows how SMTP, mailto, null, and recording senders can share the same abstraction while product-specific workflows remain in the consuming applications.
The common part is not the provider. The common part is the message.Read article
Why CancellationToken Should Flow Through the System
A practical look at why cancellation should be treated as part of an operation itself, how CancellationToken propagation affects responsiveness and resource usage, and why incomplete cancellation flow often creates hidden reliability and maintainability problems.
Cancellation belongs to operation lifetime, not to every function call.Read article
Using async and await Deliberately
A practical look at when async and await are useful in C#/.NET, when they add unnecessary complexity, and how to use asynchronous code deliberately in UI, web, repository, and application-service code.
The goal is not to make every method return `Task`. The goal is to make waiting visible where waiting is real.Read article