Content
At least, it knows the public contracts, not the internals. In addition, the onion architecture itself introduced certain problems. It took us some time to distribute functional parts between appropriate layers. But eventually, this problem was practically eliminated. The main problem with this architecture is that all layers are built on top of the Data Access Layer and are, in fact, tied to a certain type of data storage. If this type changes, it causes changes at all levels. The Entity Framework partially solves this problem, but it supports a limited number of database types.
Bounded context — each microservice is built around some business function and uses bounded context as a design pattern. The popularity of microservices is growing due to the range of benefits they offer to developers and businesses. In this article, I will tell you about my experience of using onion architecture with a harmonized combination of DDD, ASP.NET Core Web API and CQRS for building microservices. The obvious advantage of the Onion architecture is that our controller’s methods become very thin.
Good Coupling
These things should be intentionally isolated from the application core. Out on the edge, we would find a class that implements a repository interface. This class is coupled to a particular method of data access, and that is why it resides outside the application core. This class implements the repository interface and is thereby coupled to it. The basic principle of Onion Architecture solely depends on how the dependency inversion principle is applied with architecturally defined priorities between layers. Jeffrey Palermo, in his study clearly states the difference.
This is how legacy systems become stale, and eventually they are rewritten. The Service layer holds interfaces with common operations, such as Add, Save, Edit, and Delete. Also, this layer is used to communicate between the UI layer and repository layer. The Service layer also could hold business logic for an entity. In this layer, service interfaces are kept separate from its implementation, keeping loose coupling and separation of concerns in mind. At the center part of the Onion Architecture, the domain layer exists; this layer represents the business and behavior objects. The idea is to have all of your domain objects at this core.
Microservices
Often these layers are thought of as csproj projects, which would mean our API calls the application layer, which in turn calls the external APIs. An external API may provide WebHooks that call back into the infrastructure layer. Similarly, our own API may have some push functionality, such as WebHooks or SignalR. These arrows do not have to point in the same direction.
- Bounded context — each microservice is built around some business function and uses bounded context as a design pattern.
- It causes us to rely heavily on something quite external that binds the entire application together and allows it to function at run-time.
- This class is coupled to a particular method of data access, and that is why it resides outside the application core.
- The domain layers often need information or functionality in order to complete business functionality, however they should not directly depend on these.
- I’ve spoken several times about a specific type of architecture I call “Onion Architecture”.
The big drawback to this top-down layered architecture is the coupling that it creates. Each layer is coupled to the layers below it, and each layer is often coupled to various infrastructure concerns.
What is the motivation for splitting the Service layer?
Network protocols — microservices interact with each other via network protocols such as HTTP and HTTPS. Small size — smaller microservices are easier to work with. Services.Abstractions project does not reference any other project, we have imposed a very strict set of methods that we can call inside of our controllers. Great, we are done with the Infrastructure layer. Now we only have one more layer left to complete our Onion architecture implementation. The entities defined in the Domain layer are going to capture the information that is important for describing the problem domain.
Each layer bounds together concepts that will have a similar rate of change. Dependencies should be inward and never outward.