# On Aggregates and Domain Service interaction

DevFeed: [On Aggregates and Domain Service interaction](<https://devfeed.tech/articles/on-aggregates-and-domain-service-interaction-21143.md>)

Original publisher: [Read original article](<https://ocramius.github.io/blog/on-aggregates-and-external-context-interactions/>)

Published: 2017-01-25T00:00:00Z

Content type: tutorial

Language: en

Sources: [Marco Pivetta](<https://devfeed.tech/sources/marco-pivetta.md>)

Topics: [Object-relational mapping](<https://devfeed.tech/topics/orm.md>), [Code](<https://devfeed.tech/topics/code.md>), [Dependency injection](<https://devfeed.tech/topics/dependency-injection.md>), [API](<https://devfeed.tech/topics/api.md>), [App](<https://devfeed.tech/topics/app.md>), [Databases](<https://devfeed.tech/topics/databases.md>)

Tags: [api](<https://devfeed.tech/tags/api.md>), [architecture](<https://devfeed.tech/tags/architecture.md>), [code](<https://devfeed.tech/tags/code.md>), [dependency-injection](<https://devfeed.tech/tags/dependency-injection.md>), [frontend](<https://devfeed.tech/tags/frontend.md>), [orm](<https://devfeed.tech/tags/orm.md>), [payment](<https://devfeed.tech/tags/payment.md>), [shopping](<https://devfeed.tech/tags/shopping.md>)

## AI overview

This article examines where to place I/O and domain-specific validation when working with aggregates in CQRS, event-sourced architectures, and imperative ORM entity code. Using a shopping-cart payment example, it discusses commands, aggregates, command handlers, guards, dependency injection, and the problem of moving business rules into application-layer handlers.

## Source excerpt

Some time ago, I was asked where I put I/O operations when dealing with aggregates. The context was a CQRS and Event Sourced architecture, but in general, the approach that I prefer also applies to most imperative ORM entity code (assuming a proper data-mapper is involved). Scenario Let's use a practical example: Feature: credit card payment for a shopping cart checkout Scenario: a user must be able to check out a shopping cart Given the user has added some products to their shopping cart When the user checks out the shopping cart with their credit card Then the user was charged for the shopping cart total price Scenario: a user must not be able to check out an empty shopping cart When the user checks out the shopping cart with their credit card Then the user was not charged Scenario: a user cannot check out an already purchased shopping cart Given the user has added some products to their shopping cart And the user has checked out the shopping cart with their credit card When the user checks out the shopping cart with their credit card Then the user was not charged The scenario is quite generic, but you should be able to see what the application is supposed to do. An initial implementation I will take an imperative command + domain-events approach, but we don't need to dig into the patterns behind it, as it is quite simple. We are looking at a command like following: final class CheckOutShoppingCart { public static function from( CreditCardCharge $charge, ShoppingCartId $shoppingCart ) : self { // ... } public function charge() : CreditCardCharge { /* ... */ } public function shoppingCart() : ShoppingCartId { /* ... */ } } If you are unfamiliar with what a command is, it is just the object that our frontend or API throws at our actual application logic. Then there is an aggregate performing the actual domain logic work: final class ShoppingCart { // ... public function checkOut(CapturedCreditCardCharge $charge) : void { $this->charge = $charge; $this->raisedEvents[