1

In DDD, I've seen the following code many times where an entity is passed as parameter to the save method of a repository.

class MysqlUserRepository
{
    public function save(User $user) {}
}

As far as I know, infrastructure shouldn't know anything about domain. If this is correct, what am I missing here?

jerkan
  • 685
  • 2
  • 10
  • 28
  • https://learn.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/infrastructure-persistence-layer-design – Stark Jul 25 '21 at 20:31
  • The domain doesn't have any persistence knowledge or care how you store the objects. – Stark Jul 25 '21 at 21:06

3 Answers3

3

A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection.

See: https://martinfowler.com/eaaCatalog/repository.html

Repository is a mediator that has to "translate" from persistence to domain and vice versa. Persistence infrastructure get/gives "raw" data so there has to be something that allows to glue these two worlds in the most possible decoupled way. That means Repository has to know both worlds.

jlvaquero
  • 8,571
  • 1
  • 29
  • 45
3

As ar as I know, infrastructure shouldn’t know anything about the domain

That's a valid point, which I believe can be concluded from Eric Evans his book “Domain-Driven Design”. Note however, that Eric Evans leaves us somewhat in a paradoxal state.

In his book he talks about a layered architecture, from top to bottom: “User Interface” —> “Application” —> “Domain” —> “Infrastructure”.

With it, he states:

The essential principle is that any element of a layer depends only on other elements in the same layer or on elements of the layers “beneath” it.

From this we can conclude that the infrastucture layer (being beneath the domain layer) should have no knowledge about the domain layer. However, Evans also talks about the domain layer being the layer that defines the repository. In other words, we've reached an impossible state.

Since then, more has been written about Domain-Driven Design and I believe it was Vaughn Vernon’s book “Implementing Domain-Driven Design” that comes with a solution.

Instead of using a layered architecture, we could use Hexagonal Architecture defined by Alistair Cockburn. The mind-shift with Hexagonal Architecture is that the application is no longer an asymmetric, top-down, layered architecture. Instead it places the domain layer at the center. Everything else, including the infrastructure layer is placed outside this center (or hexagon). Communication is possible using ports defined by the domain "layer". The Repository can be seen as an example of such a port.

So the Domain layer can expose a port, in your case UserRepositoryInterface. Following Hexagonal Architecture, the infrastructure layer is allowed to communicate with the domain "layer". As such, it can implement the interface with MysqlUserRepository.

Nando
  • 358
  • 3
  • 13
1

... infrastructure shouldn't know anything about domain. If this is correct ...

This isn't correct. In DDD, infraestructure layer depends on domain layer, so it knows anything the domain wants to show. There's no rule in DDD about how many things the domain should show. It's up to you: you can show the whole entity, you can show a DTO, a DPO, ...

On the other hand, domain doesn't know anything about infraestructure (this is correct).

choquero70
  • 4,470
  • 2
  • 28
  • 48