Clean Architecture and CQRS in .NET: when they are worth it

Both patterns are a trade-off, not a moral standard: early verbosity in exchange for the ability to change later. When that trade pays off.

Clean Architecture and CQRS in .NET: when they are worth it

Clean Architecture and CQRS appear in almost every article about .NET today, but few explain when they are worth the effort and when they only add weight. This article looks at both in terms of cost — what you gain and what you pay.

What Clean Architecture solves

The core idea is short: business rules must not depend on the database, the framework or the user interface. Dependencies point inwards only.

In a .NET solution the common split is four layers:

  • Domain — entities, constants, value types. References nothing outside.
  • Application — business flows, commands and queries, abstractions for anything external.
  • Infrastructure — data access, mail, file storage, external service calls.
  • WebApi — entry points, authentication, routing, dependency registration.

The real benefit: when you change how data is stored or which mail library you use, the part holding business rules is untouched. Just as important, business rules become testable without standing up a database.

What you pay

There is no free lunch. Three visible costs:

  • More files for the same work. Even a simple feature needs a command, a handler, a validator and mapping. For an application that only reads and writes rows, that is pure overhead.
  • Harder to follow for newcomers. Compensate with consistent naming and folder conventions — good conventions matter more than a pretty architecture diagram.
  • Easy to apply halfway. One direct database call from the application layer is enough to break the benefit of the whole structure, and nobody notices immediately.

CQRS: separating the read and write paths

CQRS is often confused with needing two databases. At its most practical, CQRS only means this: commands that change data go one way, queries that read data go another, and the two do not share a model.

Why it is worth doing:

  • The write path needs rule checks, audit logging and intact transactions.
  • The read path needs exactly the data the screen requires, in as few round trips as possible, and usually without entity change tracking.

When both paths share one model, the read path drags fields it does not need, while the write path is stretched to fit display requirements. Separating them makes both simpler.

The pipeline — where CQRS pays off most

When every operation passes through one middle point, repeated concerns are handled once for the whole system:

  • Input validation runs automatically before the handler, with no need to repeat it in each place.
  • Logging and timing for every operation, revealing slow spots without scattering code.
  • Uniform error handling, so every business error reaches the front end in the same shape.
  • Transactions opened and closed in one place, instead of depending on a developer remembering the right call.

When not to use it

A small application with a short life, a few master-data screens and a team of one or two: a light layered structure is enough, and will be finished sooner.

Thresholds that justify the full structure:

  • The system is expected to live for years and change maintainers.
  • There are genuine business rules, not just data entry forms.
  • Several entry points share the same business logic: web UI, mobile app, background jobs, external integrations.

Common mistakes in practice

  • Entities swelling into containers for everything. If the domain model carries properties that exist only for display, the boundary has started to blur.
  • Handlers calling other handlers. Extract the shared part into its own service so the flow still reads top to bottom.
  • Too many abstractions. An interface with exactly one implementation that does not help testing deserves a second look.
  • Testing only at unit level. The most error-prone part is usually the data query, and queries reveal their problems only when run for real.

Conclusion

Clean Architecture and CQRS are not moral standards; they are trade-offs: you accept early verbosity in exchange for the ability to change later. For enterprise management systems — many business rules, constant change, a lifespan measured in years — the trade is usually worth it. For an internal tool used for a few months, it is not.

Back to all articles

Need advice on your specific problem?

What is written here are general principles. Your business has its own context - let the NinePlus team talk it through with you directly.