Clean Architecture vs Onion Architecture vs Hexagonal Architecture

Clean Architecture vs Onion Architecture vs Hexagonal Architecture

6 min read··

clean-architecturedotnetsoftware-architecture

Clean Architecture, Onion Architecture, and Hexagonal Architecture come up in every discussion about structuring .NET applications. They're often treated as competing options, but all three defend the same idea: business logic at the center, infrastructure at the edges. In a .NET solution, they even produce nearly identical project structures. Here's what actually differs, what's just naming, and how to pick one without losing a week to the debate.

Three Names, One Goal

If you've been reading about software architecture, you've probably encountered three similar-looking approaches:

  • Clean Architecture (Robert C. Martin, 2012)
  • Onion Architecture (Jeffrey Palermo, 2008)
  • Hexagonal Architecture / Ports and Adapters (Alistair Cockburn, 2005)

They all aim at the same thing: keep your business logic independent of frameworks, databases, and external concerns.

The core insight behind all three is the Dependency Rule - dependencies point inward. Infrastructure depends on your domain, never the other way around.

So what's actually different?

Hexagonal Architecture (Ports and Adapters)

Hexagonal Architecture was the first of the three, introduced by Alistair Cockburn in 2005.

The key concept is simple: your application has a core (the hexagon) surrounded by ports and adapters.

  • Ports are interfaces that define how the application talks to the outside world (and vice versa)
  • Adapters are implementations that connect those ports to real infrastructure

There are two types of ports:

  • Driving ports (primary) - how the outside world talks to your application (e.g., an HTTP controller calling a use case)
  • Driven ports (secondary) - how your application talks to external systems (e.g., a repository interface for database access)

The hexagon itself contains your business logic. It doesn't know about HTTP, databases, or message queues.

Strengths:

  • The ports/adapters mental model is intuitive
  • Makes testability explicit - you test by plugging in fake adapters
  • Symmetric - treats all external concerns equally (UI, database, messaging)

In .NET terms: Your domain and application logic sit in one project. Interfaces (ports) define the boundaries. Infrastructure implementations (adapters) connect to real systems.

Onion Architecture

Jeffrey Palermo introduced Onion Architecture in 2008, building on the hexagonal idea with a more explicit layer structure.

The architecture is organized in concentric rings:

  1. Domain Model (center) - entities, value objects, domain logic
  2. Domain Services - business operations that span multiple entities
  3. Application Services - use case orchestration, DTOs
  4. Infrastructure (outer ring) - database, file system, external services

The rules are:

  • Inner layers define interfaces
  • Outer layers provide implementations
  • Dependencies always point inward

Strengths:

  • Clearer layer separation than hexagonal
  • Explicit placement of domain services
  • The "onion rings" visualization is easy to communicate

In .NET terms: You typically create separate projects for each ring - Domain, Application, Infrastructure, and Presentation.

Clean Architecture

Robert C. Martin formalized Clean Architecture in 2012, combining ideas from hexagonal and onion architectures.

The layers are:

  1. Entities (Enterprise Business Rules) - core business objects
  2. Use Cases (Application Business Rules) - application-specific logic
  3. Interface Adapters - controllers, presenters, gateways
  4. Frameworks & Drivers - web framework, database, external tools

Clean Architecture adds explicit concepts like:

  • Use Cases as first-class citizens
  • Input/Output boundaries between layers
  • The Dependency Rule stated explicitly

Strengths:

  • Most prescriptive of the three - clear guidance on where things go
  • Use cases are front and center
  • Strong community adoption in .NET (thanks to common templates and structured guides)

In .NET terms: The typical project structure is Domain, Application, Infrastructure, Presentation - which happens to match the Onion Architecture layout closely.

Side-by-Side Comparison

Here's how the three approaches stack up:

Hexagonal (2005)Onion (2008)Clean (2012)
Core conceptPorts and adapters around an application coreConcentric rings with the domain model at the centerThe Dependency Rule plus use cases as first-class citizens
Layer namesApplication, Ports, AdaptersDomain Model, Domain Services, Application Services, InfrastructureEntities, Use Cases, Interface Adapters, Frameworks & Drivers
Primary focusTreating all external systems symmetricallyLayer discipline and interface ownership by inner ringsIsolating application-specific business rules
Testing approachSwap real adapters for fakesMock the interfaces defined by inner layersTest use cases independently of infrastructure
PrescriptivenessLow, a mental model more than a structureMediumHigh, the most opinionated of the three
.NET adoptionModerate, the terminology shows up more than the literal structureModerate, historically popular in the .NET community where it originatedVery high, with widely used templates and guides

What They Have in Common

All three share these core principles:

  1. Business logic at the center - domain code has zero dependencies on infrastructure
  2. Dependency inversion - outer layers depend on inner layers, never the reverse
  3. Testability by design - you can test business logic without databases, HTTP, or external services
  4. Framework independence - swapping a web framework or database shouldn't require rewriting business rules
  5. Interfaces as boundaries - abstractions define how layers communicate

In practice, a .NET solution following any of these three architectures looks remarkably similar. The same four rings show up under different names, with dependencies always pointing inward:

The four concentric rings shared by Clean, Onion, and Hexagonal architectures, each labeled with the equivalent term from all three: the core is Entities, Domain Model, or Core; the outer ring is Frameworks and Drivers, Infrastructure, or Adapters

The naming differs. The structure is nearly identical.

Which Should You Choose?

Honestly? It doesn't matter as much as you think.

All three solve the same problem. If you understand the core principles - dependency inversion, business logic at the center, infrastructure at the edges - you can build clean systems with any of them.

That said, here's a practical decision guide:

Choose Clean Architecture when:

  • You want clear, prescriptive guidance
  • Your team benefits from a well-known, widely documented approach
  • You're building in .NET (the ecosystem has strong support with templates and courses)

Choose Hexagonal when:

  • You want maximum flexibility in how you structure things
  • You work in a polyglot environment where the ports/adapters terminology is common
  • You're focused on adapter swappability (testing, multi-channel systems)

Choose Onion when:

  • You want layer discipline without the prescriptiveness of Clean Architecture
  • You prefer the rings mental model for communicating with your team

Or don't choose at all: If your project is simple, a Vertical Slice Architecture might be more practical. Not every project needs concentric rings. I've written a separate guide on when to use Clean Architecture if you're on the fence.

Common Mistakes

1. Treating the choice as binary. You can mix ideas. Use Clean Architecture's use case structure with Hexagonal's ports and adapters terminology. The principles are compatible.

2. Over-engineering small projects. A CRUD API with five endpoints doesn't need four projects. Start simple and add architecture when complexity demands it.

3. Arguing about names instead of principles. The Dependency Rule matters more than whether you call it a "port" or an "interface". Focus on the direction of dependencies, not the labels.

4. Forgetting that architecture is a means, not an end. The goal is maintainable, testable software. If your architecture makes the codebase harder to work with, you've missed the point.

Summary

Clean Architecture, Onion Architecture, and Hexagonal Architecture are variations of the same idea: protect your business logic by making infrastructure depend on your domain, not the other way around.

They differ in naming, structure, and emphasis - but the principles are identical.

Pick the one your team understands best, and focus on applying the principles consistently.

Thanks for reading, and stay awesome!


Frequently Asked Questions

What is the difference between Clean Architecture and Onion Architecture?

Very little in practice. Both organize code in concentric layers with dependencies pointing inward. Clean Architecture is more prescriptive: it makes use cases first-class citizens and explicitly states the Dependency Rule. Onion Architecture emphasizes the ring structure and domain services.

Is Hexagonal Architecture the same as Ports and Adapters?

Yes. Hexagonal Architecture and Ports and Adapters are two names for the same pattern by Alistair Cockburn. Ports are the interfaces at the application boundary, and adapters are the infrastructure implementations that plug into them.

Which architecture is best for .NET projects?

Clean Architecture has the strongest .NET ecosystem support with templates, courses, and community guidance. But all three produce nearly identical solution structures in .NET, so the principles matter more than the label.

Can you combine Clean, Onion, and Hexagonal Architecture?

Yes. The three approaches are compatible because they share the same core principle of dependency inversion. Many teams use Clean Architecture project structure with ports-and-adapters terminology for their interfaces.

Do all three architectures require multiple projects in .NET?

No. The layering is logical, not physical. You can apply the dependency rule inside a single project using folders and architecture tests, although separate projects make violations harder to introduce.

Loading comments...

Whenever you're ready, there are 4 ways I can help you:

  1. Pragmatic Clean Architecture: Join 5,000+ students in this comprehensive course that will teach you the system I use to ship production-ready applications using Clean Architecture. Learn how to apply the best practices of modern software architecture.
  2. Modular Monolith Architecture: Join 2,800+ engineers in this in-depth course that will transform the way you build modern systems. You will learn the best practices for applying the Modular Monolith architecture in a real-world scenario.
  3. Pragmatic REST APIs: Join 1,900+ students in this course that will teach you how to build production-ready REST APIs using the latest ASP.NET Core features and best practices. It includes a fully functional UI application that we'll integrate with the REST API.
  4. Patreon Community: Join a community of 5,000+ engineers and software architects. You will also unlock access to the source code I use in my YouTube videos, early access to future videos, and exclusive discounts for my courses.

The .NET Weekly

Become a Better .NET Software Engineer

Join 66,000+ engineers who are improving their skills every Saturday morning.