Dependency Inversion

Handling users is not the responsibility of the Service. As we saw in Chapter 10Repositories, there's a specialized class that deals with User collections: the User Repository. This is a dependency from the Application Service to the Repository. We don't want to couple the Application Service with a concrete implementation of the Repository, as then we'd be coupling our Service with Infrastructure details. So we depend on the contract (interface) that concrete implementations depend on, the UserRepository.

A specific implementation of the UserRepository will be built and passed in at runtime — for example, with DoctrineUserRepository, a specific implementation that uses Doctrine. Passing a specific implementation will also work when testing. For example, NotAvailableUserRepository can be a specific implementation that will throw exceptions each time an operation is performed. This way, we can test all Application Service behaviors, including sad paths, which is when the application must behave properly, even if something goes wrong.

Application Services could depend on Domain Services like GetBadgesByUser too. At runtime, the implementation for such a Service could be quite elaborate. Imagine an HttpGetBadgesByUser for integrating a Bounded Context through HTTP protocol.

Depending on abstractions, we'll make our Application Service immune to low-level Infrastructure changes.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset