P
P
phenya2019-10-30 13:51:36
PHP
phenya, 2019-10-30 13:51:36

"Deleting" an aggregate in DDD?

I understand with DDD and I can not understand who performs actions on aggregates. In particular, for example, the action reflecting the "removal" of the aggregate.
For example, there is an aggregate Catalog of goods (Catalog) with the root entity Catalog and value objects CatalogID, Name.
There is a storage, using which we can pull out the unit, change it and save it back

$catalog = $repository->find($catalogId);
$catalog->rename('Some another name')
$repository->update($catalog);

Also within another bounded context, there is an Integration aggregate, with an Integration root entity, objects with values ​​of IntegrationId, Name, and a collection of objects with values ​​of EntityRelations. Using this aggregate, we have the opportunity to connect our any entity from the subject area with the entity of a third-party integrated service (ERP, 1C)
...
$integration->addRelation(new EntityRelation('catalog', $catalog->id(), $externalCatalogId));
$integrationRepository->update($integration);

And now the actual question is, how do I "remove" the directory in such a way that it is "removed" along with all the integration links? Obviously, you can enter the "CatalogDeleted" event, subscribe to it and "delete" the integration links associated with this catalog. But how does the Catalog know that it is "deleted"?
There is an idea inside the Catalog entity to declare a protected onDelete() method, and to pull it in the repository through reflection.
class Catalog extends AbstractEntity
{
   ...
   protected function onDelete()
   {
       $eventManager->dispatch(new CatalogDeleted($this->id()));
   }
   ...
}

class CatalogRepository extends AbstractRepository implements CatalogRepositoryInterface
{
   ...
   public function delete(Catalog $catalog)
   {
        $method = new \ReflectionMethod($catalog, 'onDelete');
        $method->setAccessible(true);
        $method->invoke($catalog);
        //дальше удаляем из БД
   }
   ...
}

Can this approach be considered normal?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
X
xfg, 2019-10-31
@xfg

Your idea is correct, but instead of the protected onDelete, they make the usual public remove method, which does nothing, but simply throws out a domain event. This method, like all the others, is simply called inside the application service, and then removed from the repository.
$catalog->remove();
$repository->remove($catalog);
To be atomic, you need to throw out events after changes have been made in the database. The event itself must also be saved to the database, in one transaction with the creation / update / deletion of data about the unit. Some thing must then remove the handled events. Some thing should push events from the database, which for some reason live there for too long - to subscribers. It usually happens on failure, when the event was written to the database, but not sent to the subscribers.
Some complicated confused crap with event consistency is obtained. It also happens that the one who received the event cannot process it, since some invariant in its domain model is violated and sends an event about failure, to which the one from whom the event came should respond. More than three steps and it is completely incomprehensible which events fly where, who reacts to them, and what generally happens in such a system.
Therefore, I would try Saga Orchestration, this is such a thing that describes step by step which services need to be called in order to successfully complete a business operation, as well as what actions need to be performed at each step in case one of the services involved in a business operation fails in order to to return the entire system to a consistent state.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question