Since lesson 1.4.4, the Kladde has had a contract for its store, IKladdeStore, and two implementations since then: the JSON file for the
program and the store in memory for the tests. In this lesson a third one joins them, with EF Core and SQL Server. After that you change a
single line in Kladde.Web, and the Kladde works with the database. The endpoints don’t notice, and the tests from module 2.3 keep running
without you changing a line in them.
That it works so easily is no accident. It’s the reward for a decision you made in K1: The core decides what it needs from the store, and it doesn’t know a single one of them.
Ports and adapters
The Kladde is built on a pattern called ports and adapters (also hexagonal architecture):
- A port is a contract that the core defines because it needs something from outside.
IKladdeStoreis such a port: “Load everything, save everything, and reject whatever clashes with a simultaneous change.” It lives inKladde.Core. - An adapter implements a port with a particular technology.
JsonKladdeStoreinKladde.Fileswith a file,InMemoryKladdeStoreinKladde.Corewith a list, and nowEfKladdeStoreinKladde.Datawith SQL Server.
The dependencies all point inward:
Kladde.Web ──────► Kladde.Core ◄────── Kladde.Data (EF Core, SQL Server)
│ ▲
│ └────────────── Kladde.Files (JSON)
└──► Kladde.Data (only to put everything together in Program.cs)
Kladde.Core references nothing. Kladde.Data knows the core; the core doesn’t know Kladde.Data. Kladde.Web knows both, but only in one
place that really matters, Program.cs, where everything is put together (lesson 2.3.3). The endpoints get an IKladdeStore and don’t know
which one. Whoever swaps the store later changes one line in Program.cs, not twenty endpoints.
The Kladde makes one deliberate exception: ContactDirectory from lesson 2.4.9 reads directly with EF Core, and a page or an endpoint may
use it. Reading for a display needs no rule of the model, and a search in SQL is exactly what the port can’t do. Changing, on the other hand,
always goes through KladdeBook and therefore through the port.