Is it a recipe? Sure. Is it advice on how to NOT make spaghetti? Also, yes. Does the article belong into Software development category? Of course, what is wrong with you? Are you interested? Great, then read more.
Okay, now it is time to explain what the hell am I talking about. Onion architecture is an approach to design layers of an application. Spaghetti or also the spaghetti code is the code, that is harshly separable, tangled and passes through multiple layers of an application. Such code is hard to maintain and hard to extend with any new features. So, Onion architecture is some kind of recipe telling you how to NOT make spaghetti.
As we know, it is simple to detach layers from an onion as well as attach them back again Alright, I guess nobody is attaching onion layers back to an onion, but it can work well as an example for our imagination. Architecture of an onion consist of core and layers. What should be the core in a software application?
Should it be a Presentation of an application? Let me explain. By the phrase Presentation of an application, I mean the part of an application, that is responsible for user interface. In software development, such part is powered by different technologies like WPF, Angular and React. And what is the Presentation of onion? I´d say it's just a peel. From the measurement point of view, the peel is too far away from the core. So, the Presentation of an application cannot be the core.
Should it be a Database? Let's think about it. In a database, we can find information. What information about an onion we know? Onion can have a different colour, kind, taste or look. If information can have different values, they are variable. If something is variable, we can't rely on it. We don't have a solid core. So, the database cannot be a core either.
What defines an onion by nature? In my humble opinion, it is its genetic information. Genetic information defines how the onion looks like, how it tastes etc. Genetic information formulates the onion. And what is genetic information? Well, it is nothing more than a set of rules.
What or who is forming software applications? Developer? I don't think so. Simply said, the developer is translating tasks from human language to the language of the computer. So, the software applications are shaped from tasks by humans? Yes! And what are those tasks? Tasks are a list of criteria that the application should do. In software engineering, we have a name for one criterium on the list and it is the Business rule. So, the result of our brainstorm is:
In the domain layer, we will keep entities and value objects of our application. Entity is every class that is describing the behaviour of the object in real-world, which uniqueness is defined by the value of its identifier. For example, human uniqueness is defined by his or her personal identification number. On the other hand, the Value Object's uniqueness is defined by its value. For example, a phone number or an address.
Part of the core called Application contains every work done with entities or value objects. In the introduction, I talked about tasks or business rules. Example of business rule could be a task "Save customer." But wait, such a rule will have to work with the database. And at the introduction, we made it clear that the database should not be a part of the application's core. So where is the database?
Database can be found in the Persistence layer, marked by green colour in the picture above. In the picture is an arrow pointing at the dependency of the Persistence layer to the Application layer. More precisely Application layer must not use any classes defined in the Persistence layer.
How can we even implement "Save customer" task without a possibility of invoking methods of class in Persistence layer? Persistence layer in Onion architecture can be pictured as a Plugin for the Application layer. What do we need to plug in the plugin? Interface. Where will be an Interface? Well, in the core of the application. We will hold our interface in the Application layer and its concrete implementation will be implemented in the layer of the plugin, in our case, in the Persistence layer. This approach is called Dependency inversion principle. By implementing such an approach, we are achieving database technology independence. Database becomes an implementation detail and our core is completely separated from possible external influences caused by the database.
Separation of the Presentation layer also brings another advantage. There are more and more electronic devices and every developer will agree with me if I say that the Presentation layer will work best if it is developed in native technology.
Last but not least, the Infrastructure layer. The Infrastructure layer serves for bulking implementations of communications with external technologies. We don't want to depend on external technologies. For example, it can be a technology responsible for sending emails or file printing.
Onion architecture is a concrete implementation draft inspired by book Clean Architecture, which author is Robert C. Martin. Mentioned version of Onion architecture was designed by software architect Jason Taylor. Complete repository with sample of implementation can be found at Github.
By using Onion architecture, we can reach the separation of vital rules from the outer world's technologies. If we don't tangle into our business rules outer technologies, we can manage the change of technologies more easily. Architecture brings easier use of modern development approaches like Domain-Driven Design and Test-Driven Development.