I see only benefits to the onion architecture over the 3 layered architecture where the BL had responsibility to call methods on DAL (or an interface of DAL) to do CRUD. The onion has better separation of concerns, testability, maintainability and is cleaner.

So is the onion architecture indeed better in all aspects and 3 layered architecture is just an old way of doing things, or there are some scenarios where I should prefer to use the 3 layered architecture, if so - which?


2 Answers 2


Layers, Onions, Ports, Adapters: it's all the same

Since this article makes clear that onion is equivalent to 3 layer + application of the Dependency Inversion Principle (DIP), then the question becomes "where should I prefer to use DIP?" I'd say any non-toy project. Using DIP allows the core of your code to be more isolated, testable and maintainable. When you really don't care about that is when it's a throw-away project or when you are trading maintainability for performance.

Also, don't confuse DIP with DI (Dependency Injection) containers. One doesn't imply the other.

  • From the Layers, Onions ... link above, I don't understand how the UI will retrieve some domain entities without Data Access Library. For example, let's consider Person Domain. To obtain a list of people from UI, don't we need the Data Access Library? That means UI is dependent on Data Access Library. No?
    – bostonjava
    Commented Apr 23, 2020 at 17:04
  • 1
    @bostonjava The idea behind dependency inversion is for the dependency to be the other way around. The Person domain defines the data structure, and the DAL depends on that and loads data into it. But the Person domain doesn't know anything about it and basically takes no side effect dependencies. App/infrastructure services are responsible for organizing side effects like loading from DB and invoking domain behaviors. Since the core business code has no outside entanglements, it is easier to test and maintain. Commented Jul 8, 2020 at 20:01

I don't think the accepted answer gives a full picture, these principles are very similar but differ a bit in approach and philosophy.


Onion: Domain model is correct, data reflects domain model.

Layered: Data is correct, domain model reflects data.


Onion puts the Domain Model, such as POJO and rich domain classes at the center of the application where persistence is a plugin to the application.

You have an Order with Items. You add the item to the order
object itself then persist it with a tool.

var order = yourOrder;
// assigns the order id or uses maybe an ORM to handle it
order.AddItem(item); Orders.Update(order);


Layered puts the data itself in the center. The data is then interacted through the domain model to get a rich representation of the data.

Order has items.
To add item to Order you add an Item with reference to the Order.
To get the updated order you can reload the order with the items to get the updated version of the data according to the DB.

Order = Orders.Read(orderId, { withItems = true })

Common features

UI, API, authentication, services and use cases are the same in both. The outside interacting with the application is the exact same.


Not to say that the DB should decide how the application should look like but I feel like Onion is more suited towards document databases like MongoDB since you don't need complex mapping, persisting etc. If you have an SQL DB I would rather like to say "insert into Table ..." and assume the data is correct because of a strongly enforced schema.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.