Dennis Doomen
@dennisdoomen
Microsoft MVP | Coding Architect | .NET Tech Lead | .NET & C# | TypeScript | Fluent Assertions Author | International Speaker | Occasional Trainer | React & VueJS | Event Sourcing Veteran | DDD Designer | TDD Practitioner | Clean Code Writer
Choosing between records and classes in C# matters! Records: data-focused, immutable, structural equality (DTOs, value objects) Classes: behavior-focused, mutable state, identity-based Record struct: small immutable values (stack allocation) Mix them and you've got a design problem. #CSharp
In general, if you find a lot of data-only classes in your code base, you probably also have a few (static) classes with a lot of behavior. Use the principles of object-orientation explained and move the logic close to the data it applies to. ⚠️The only exceptions to this rule are classes...
If you find yourself writing code like this someObject.SomeProperty.GetChild().Foo() ...then you may be violating the Law of Demeter. An object should not expose other classes it depends on, because callers may misuse that exposed property or method to access the object behind it...
In other words, you should be able to pass an instance of a derived class wherever its base class is expected, without the callee knowing the derived class. A very notorious example of a violation of this rule is throwing a NotImplementedException when overriding methods from a base...
Did you know there's a great way to start building an (open-source) library in .NET that comes with everything you'd expect from a professional package? And did you know it supports GitHub and Azure DevOps? If not, check out github.com/dennisdoomen.... Version 1.9 was released over the weekend.
Interfaces should have a name that clearly explains their purpose or role in the system. Do not combine many vaguely related members on the same interface just because they were all on the same class. Separate the members based on the responsibility of those members, so that callers only need...
It used to be easy to name my favorite developer conference, but after two days at @wearedevelopers.bsky.social World Congress in Berlin, I have to reconsider. With 10–15,000 attendees, it's less like a traditional developer conference and more like a tech festival.
If a constructor dependency is only used by a single method, ask whether it belongs there at all. Passing it as a method parameter often produces a cleaner API and keeps the constructor focused on what the object actually needs.
This Wednesday, I'll be travelling to #Berlin to join the @wearedevelopers.bsky.social World Congress. On Thursday, I'll be conference speaker and workshop trainer. And then on Friday, I'll be the stage moderator for half a day. Can't wait to be there again. Will I see you there?
A class should do one thing well. It can model a primitive value like EmailAddress or ISBN, represent a business concept, hold plain data, or coordinate other classes. It should not do a mix of those. Good SRP warning signs: ❌And in the name ❌Hard to name or explain ⬇️
Using AI tools to generate, suggest or refactor code is fine, but you are fully responsible for every line that ends up in the codebase. Do not merge AI-generated code without reviewing it, understanding it and verifying that it meets the same quality bar as hand-written code.
Today, I'll drive to one of my favorite conferences in Germany, the wonderful Developer World - DWX. This year is going to be quite busy. I won't just do one, not two, but three different talks, all new and shiny. Can't wait to immerse myself in the Germany hospitality. Will I see you there?
Object-oriented design rests on four core principles. Understanding them is one thing; applying them correctly is what leads to maintainable software. #csharp #dotnet #softwareengineering
YAGNI isn't about avoiding change. It's about avoiding premature complexity. Don't add abstraction layers, extension points, or configuration options for requirements that don't exist yet. Build for today's needs. Refactor when tomorrow arrives.
The simplest solution that fully solves the problem is usually best. Complexity makes code harder to read, test, debug and change. Avoid over-engineering, unnecessary abstraction, or clever tricks. If a junior dev can't grasp in one pass, it's too complex. Simplicity is a feature.
Choose intuitive, predictable code. No surprises in naming, behavior, or side effects. Name clearly. Avoid side effects in getters. Follow conventions. Don’t break patterns without strong reason. Ask: would an experienced dev expect this?
Released .NET Starter Kit v1.8 for building binary or source-only NuGet packages via GitHub or AZDO. New: .slnx solutions, Azure DevOps pipeline templates, C# Coding Guidelines skills, .NET 10, updated dependencies, a Fallout-based build pipeline, and .editorconfig refinements.
Released Mockly 1.7 + FluentAssertions.Mockly. What's new? Request header matching, generic For(HttpMethod)/Head/Options, ProblemDetails responses, file/stream/bytes responders, query & form matching, response headers, new assertions, and automatic agent skill registration. mockly.org
Back from the Kraków edition of @updateconference.bsky.social. Two talks, great conversations, plenty of laughs, and a flawlessly organized event. Huge thanks to the crew, and everyone who made it such a memorable week. #dotnet #csharp #community
⚙️ Design patterns give developers a shared vocabulary: Repository, Factory, Strategy, Observer, Decorator, etc. Well-known patterns make code easier to understand, extend, and maintain. 💡 If a class fits multiple patterns, it may be doing too much. #csharp #designpatterns
Mockly 1.6 will now automatically create a skill in your project's .agents/skills folder to help get the most out of HTTP mocking in .NET. Check out it out at github.com/dennisdoomen...
Today and tomorrow, I'll be at the Polish edition of the amazing UpdateConf Krakow. I'm not just doing one, but two separate sessions. Will I see you there?
I’ve refreshed csharpcodingguidelines.com with new General Guidelines, a dedicated Testability section, updated modern C# guidance, and a rule for AI-generated code: use it if it helps, but own every line. The repo now also includes Skills for AI-assisted reviews. See github.com/dennisdoomen...
⚔️ Last week at Techorama Belgium, I took over room 6 at Kinepolis Antwerp talking about building HTTP APIs in .NET! Covered: responsibility levels, versioning, OpenAPI docs, error/success codes, async APIs, minimal API & more. So much devs often overlook here. 🧵
🎤 Speaking at Techorama Belgium again! I'll share what I've learned about building professional HTTP APIs in .NET — API design, HTTP error codes, async APIs, caching, versioning, contract design, concurrency & OpenAPI. Will I see you there? #Techorama #dotnet #csharp