How can we fix this? As the Domain Model layer depends on concrete infrastructure implementations, the Dependency Inversion Principle, or DIP, could be applied by relocating the Infrastructure layer on top of the other three layers.
High-level modules should not depend on low-level modules. Both should depend on abstractions.
Abstractions should not depend on details. Details should depend on abstractions. Robert C. Martin
By using the Dependency Inversion Principle, the architecture schema changes, and the Infrastructure layer — which can be referred to as the low-level module — now depends on the UI, the Application layer, and the Domain layer, which are the high-level modules. The dependency has been inverted.
But what is Hexagonal Architecture, and how does it fit within all of this? Hexagonal Architecture (also known as Ports and Adapters) was defined by Alistair Cockburn in his book, Hexagonal Architecture. It depicts the application as a hexagon, where each side represents a Port with one or more Adapters. A Port is a connector with a pluggable Adapter that transforms an outside input to something the inside application can understand. In terms of the DIP, a Port would be a high-level module, and an Adapter would be a low-level module. Furthermore, if the application needs to emit a message to the outside, it will also use a Port with an Adapter to send it and transform it into something that the outside can understand. For this reason, Hexagonal Architecture brings up the concept of symmetry in the application, and it's also the main reason why the schema of the architecture changes. It's often represented as a hexagon because it no longer makes sense to talk about a top layer or a bottom layer. Instead, Hexagonal Architecture talks mainly in terms of the outside and the inside.