user1129875
user1129875

Reputation: 3

Using infraestructure in use cases

I have been reading the book Patterns, principles and practices of domain driven design , specifically the chapter dedicated to repositories, and in one of the code examples it uses infrastructure interfaces in the use cases, is it correct that the application layer has knowledge of infrastructure?, I thought that use cases should only have knowledge of the domain ...

Upvotes: 0

Views: 322

Answers (2)

Subhash
Subhash

Reputation: 3270

It is the Application Layer's responsibility to invoke the (injected) infrastructure services, call the domain layer methods, and persist/load necessary data for the business logic to be executed. The domain layer is unconcerned about how data is persisted or loaded, yes, but the application layer makes it possible to use the business logic defined in the domain layer.

You would probably have three layers that operate on any request: A Controller that accepts the request and knows which application layer method to invoke, an Application Server that knows what data to load and which domain layer method to invoke, and the Domain Entity (usually an Aggregate) that encloses the business logic (a.k.a Invariants).

The Controller's responsibility is only to gather the request params (gather user input in your case), ensure authentication (if needed), and then make the call to the Application Service method.

Application Services are direct clients of the domain model and act as intermediaries to coordinate between the external world and the domain layer. They are responsible for handling infrastructure concerns like ID Generation, Transaction Management, Encryption, etc.

Let's take the example of an imaginary MessageSender Application Service. Here is an example control flow:

  • API sends the request with conversation_id, user_id (author), and message.
  • Application Service loads Conversation from the database. If the Conversation ID is valid, and the author can participate in this conversation (these are invariants), you invoke a send method on the Conversation object.
  • The Conversation object adds the message to its own data, runs its business logic, and decides which users to send it to.
  • The Conversation object raises events to be dispatched into a message interface (collected in a temporary variable valid for that session) and returns. These events contain the entire data to reconstruct details of the message (timestamps, audit log, etc.) and don't just cater to what is pushed out to the receiver later.
  • The Application Service persists the updated Conversation object and dispatches all events raised during the recent processing.
  • A subscriber listening for the event gathers it, constructs the message in the right format (picking only the data it needs from the event), and performs the actual push to the receiver.

So you see the interplay between Application Services and Domain Objects is what makes it possible to use the Domain in the first place. With this structure, you also have a good implementation of the Open-Closed Principle.

  • Your Conversation object changes only if you are changing business logic (like who should receive the message).
  • Your Application service will seldom change because it simply loads and persists Conversation objects and publishes any raised events to the message broker.
  • Your Subscriber logic changes only if you are pushing additional data to the receiver.

Upvotes: 1

Persia
Persia

Reputation: 895

Using interface to seperate from implementation is the right way, so use cases layer knows interfaces not infrastructure detail.

Upvotes: 1

Related Questions