40 practical tips for keeping
your C# code base healthy
Dennis Doomen
@ddoomen | Principal Consultant | Microsoft MVP
About Me
• Coding Architect
• .NET/C#
• Bit of TS/JS/React/Vue
• 29 years of “pro” experience
• Author of FluentAssertions, Pathy,
PackageGuard, Reflectify, .NET Library
Starter Kit
• www.dennisdoomen.com
• BlueSky, Twitter, Mastodon, LinkedIn
Establish clean source control
guidelines
Establish (HTTP) exception and logging
guidelines
Merge microservices that don't need
independent scaling
µService µService µService µService
µService µService µService µService
µService µService µService µService
µService µService µService µService
Modular Monolith
µService
µService
µService
µService
Service Service Service
Service Service Service
Align projects with the deployment or
reusability scope
Make the folder structure explain the
architecture
Keep concrete classes internal by only
exposing an interface
Use .editorconfig and Prettier to
automatically format code
Use .NET analyzers and ESLint to get
early code quality feedback
Use JetBrain’s Cleanup Profiles for auto
clean-up
Use directory.build.props and .editorconfigs to
gradually enforce standards
Document the purpose of code, not
how it does that
Organize code by functionality
Clarify code review comment intent
https://github.com/erikthedeveloper/code-review-emoji-guide
Consider Central Package Management
Directory.packages.props
MyProject.csproj
y
Name and group tests functionally
Use a well-known branching strategy
Split refactoring commits from the rest
Use fixup commits and interactive
rebases
Reduce dependencies on unstable
packages
Main Package
Application
More stable package
Contract
Contract
Source-only
package
Auxiliary
Package
Optional
Dependency
Dependency
Package
Refactor using the Rule of Three
Keep code internal
Use PolySharp to use newer C#
features
Shared Module
Module 1
Deduplicate complicated reusable code
Complicated
logic
Module 2
Complicated
logic
Module 3
Complicated
logic
Module 1
Complicated logic
Module 2 Module 3
Shared Module
Duplicate and simplify
Shared Module
Module 1
Simplified
logic
Module 2
Simplified
logic
Module 3
Simplified
logic
Module 1
Overly generic code
Module 2 Module 3
Shared Module
Split shared projects to reduce
dependencies
Shared Project
Project 1 Project 2 Project 3
Project 1 Project 2 Project 3
Shared Project
Shared Project
Shared Project
Replace lots of dependencies with a
single reversed interface
MyControll
er
ISomeRepository
IExternalService
IOtherModule
Specific interface
Adapter
ISomeRepository
IExternalService
IOtherModule
MyControll
er
Get rid of separate validators and
query/handlers patterns
Finance
Controller
Some
Request
Handler
Request
validator
IValidate<RequestValidator>
IHandle<SomeRequestQuery>
Don’t forget the OO principles
Replace List<T> or Dictionary<T> with a
custom collection class
Order
OrderLine
List<
OrderLine
>
Order
OrderLine
OrderLineCollection
Don't introduce interfaces if you don't
need them
Move container registrations into the
functional folder
Split bloated interfaces
Finance
Service
IFinanceService
Finance
Service
IProvideVatRates
ICalculateIncomeTaxes
ITransactionHistory
Replace single-method interfaces with
delegates
Ensure every PR makes the code a little
bit better
Use // REFACTOR and // SMELL
comments
https://www.infoq.com/articles/natural-course-refactoring/
Keep your licenses in check
Learn to use AI assistants and agents
Spell check your code
Replace Bicep & Terraform with Pulumi
Switch to GitHub and Dependabot or
adopt Renovate
Use Nuke to evolve your build script
over time
Learn from others
Find me at
bluesky: @ddoomen.bsky.social
mastodon: @ddoomen.mastodon.social
twitter: ddoomen
email: dennis.doomen@avivasolutions.nl

Practical tips for keeping your C# code base clean