Towards Hexagonal Architecture - Dependency Inversion between Business- and Data-Access Concerns
To entirely remove any direct call from the business to the data-access concern, we need to introduce application-specific interfaces that are implemented by the data-access adapters, aka Ports.
In the last article, I showed how to separate data access from business concerns in a codebase by creating an adapter with method signatures that only contain either primitive- or application-specific data types.
By doing so, I could effectively get rid of the framework-dependent data-access types and repositories, effectively separating the two concerns.
Current Dependencies
The current application service still depends on the new data-access adapter, as can be seen below:

I want to visualise this with the following diagram. The data-access adapters effectively separate business concerns from data-access concerns by mapping between the two. Most of the passed data is currently primitive. ParkingSpot is a data structure defined within the application concern and is used by the data-access adapters.
This is actually the first step to invert the dependencies: for a truly business-centric architectural design, the data-access concern needs to depend on the business concern, not the other way round.
By employing primitive- or application-specific types in the repository adapter’s method signatures, I already have achieved half of the transformation.
However, the application service ParkingSpotReservationService still directly calls the data-access repository adapters.
Data-Access Adapters inside the Business Concern?
To achieve a pure business-centric architecture, both ParkingSpot
- and ParkingReservationRepositoryAdapters
should not directly be called by the application service anymore.
This is where Hexagonal Architecture’s Ports come in handy: we can define interfaces inside the service package / business concern, which are then implemented by these data-access adapters.
These interfaces are going to be the ports through which the business concern is interfacing and interacting with the data-access concern.
So let’s do exactly that by pulling up the method signatures of the two adapters into two interfaces ParkingSpotRepository
and ParkingReservationRepository
, which are then implemented by the respective adapters:
I use IntelliJ’s built-in features to extract a new interface and place it in the service package (for now. I will show possible package structures in a later article).



You can find the solution on the following branch: introducing-data-access-interfaces.
Dependencies after Ports Creation
After creating adapters that map between data-access- and business concern, introducing port interfaces as part of the business concern that only use either primitive- or business-concern-specific data types, and making the data-access adapters implement those interfaces, there are finally no direct calls/dependencies from the business- to the data-access concern anymore.
This can also be seen in the imports declaration at the top of the service:

The data-access concern is isolated as well, only depending on the port interface definitions of the application-service package.
This step finalises the dependency inversion, such that the business- does not depend on the data-access concern anymore, but the other way round.
It additionally illustrates the dependency relationships between ports and adapters on the driven (right) side of the diagonal line in the hexagon, as the following diagram illustrates:

Conclusion
Inverting dependencies between business- and data-access concerns is one of the most important steps to move towards a business-centric structure like Hexagonal Architecture.
The important part to remember is that the interfaces (or ports), together with the data structures they employ in their signatures, are defined within the application concern and implemented by the data-access concern. There can’t be any dependency from application- to data-access concerns!
In the next article, I will show what may still be missing until we can truly speak of Hexagonal Architecture, so subscribe if you haven’t already not to miss it:
Resources
This article is part of a series moving towards a business-centric architectural design. See the following post to get started.
This series of articles is an addition to the From Layered to Hexagonal Architecture in 2 steps article.
We touch on the same topics in our O’Reilly course “DDD, EventStorming, and Clean Architecture”. Check it out to learn how to use Classic TDD to implement DDD Aggregates in Hexagonal and Clean Architecture.
If you want to learn more about effectively separating concerns, you could also have a look at our on-premise, remote or hybrid workshop Modern Software Architecture Design Patterns.