Version B from lesson 4.10.3 put the domain in the middle and built four rings with Domain, Application, Infrastructure and Web. The lesson ended with the sentence that the hexagonal view of the same structure adds something. What exactly is the question of this lesson.

You know ports and adapters from lesson 4.3.5: core, application with ports, adapters on the outside named after their technology, and the composition in one place. That is not repeated here. This lesson says what the style means beyond those rules, and tests it twice on the follow-up: first you cut version C out of version B and measure it like A and B. Then version C gets a second entrance, a message from Service Bus instead of an HTTP call, and a git diff shows whether the middle had to change even one line for it.

What ports and adapters says beyond lesson 4.3.5

Alistair Cockburn first described the style as hexagonal architecture, later under the name ports and adapters. His goal was an application that people, other programs, automated tests and scripts can operate equally well, and that can be developed and tested without its later devices and databases. Three things follow from that goal that appeared only in passing in lesson 4.3.5.

There is no top and bottom. The picture of layers puts the user interface on top and the database at the bottom, and the code follows the picture: the top calls the bottom. The hexagon puts both on the outside, at the same height. A web interface is nothing special for the middle, it is one entrance among several. The same goes for the database on the other side. By the way, the six corners mean nothing; Cockburn chose the shape so that there is room for several ports when drawing and nobody thinks of layers.

The asymmetry lies between left and right, and it depends on who starts.

Side Who starts Who owns the port Form in code Version C Kladde
driving (left) an actor outside: person, program, test the middle; it offers it public methods of the middle FollowUpUseCases QuoteCommands
driven (right) the middle the middle; it demands it an interface that an adapter implements IFollowUpStore, TimeProvider IQuoteRepository, ICurrentUser

On both sides the port belongs to the middle, but not in the same way. On the left the adapter calls the middle, so it depends on it without any trick. On the right the middle calls the adapter, and only the dependency inversion principle from lesson 4.10.1 turns the dependency around. Whoever mixes up the two sides creates a driving port as an interface that nobody implements a second time, or lets a driven adapter call the middle.

A port has as many adapters as there are ways to the outside. A port is a purpose, "work on follow-ups" or "keep follow-ups". An adapter is a technology that serves this purpose. For the follow-up it looks like this:

Port Adapter Where
driving: FollowUpUseCases HTTP FollowUps.Http
message from Service Bus FollowUps.ServiceBus, exercise 2
test FollowUpUseCasesTests
driven: IFollowUpStore EF Core with SQLite FollowUps.Sql
in memory InMemoryFollowUpStore in the test project

The test is there on purpose. It is the first driving adapter a hexagonal application gets, even before there is a web page. With it, Cockburn's goal of operating the application without its devices is already reached.