maks-rafalko / tactician-domain-events

A Plugin for Tactician command bus library to work with the recorded Domain Events
https://maks-rafalko.github.io/tactician-domain-events/
MIT License
25 stars 4 forks source link

EventRecorderCapabilities should have recordEvents() method #4

Open JalfResi opened 6 years ago

JalfResi commented 6 years ago

It would be very convenient if EventRecorderCapabilities had the following method:

public function recordEvents(ContainsRecordedEvents $recordedEventsContainer) 
{
    foreach($recordedEventsContainer->releaseEvents() as $event) {
        $this->recordedEvents[] = $event;
    }
}

This way I wouldn't need to keep implementing it in my command handlers - I could simply call $this->eventRecorder->recordEvents($entity);

I'm happy to put this together in a pull request if you prefer.

maks-rafalko commented 6 years ago

Hello! Thanks for creating this issue.

As it is documented here, EventRecorderCapabilities is used inside Entities.

Thus, adding public function recordEvents(ContainsRecordedEvents $recordedEventsContainer) to this trait would be strange, because in this case entity will have a method to record events from another entity.

Seems like it should be separated. What if you create your own EventRecorder that extends BornFree\TacticianDomainEvent\Recorder\EventRecorder and adds this recordEvents() method?

In this case you can use it inside your commands and do not duplicate code:

class EventRecorder extends BornFree\TacticianDomainEvent\Recorder\EventRecorder
{
    public function recordEvents(ContainsRecordedEvents $recordedEventsContainer) 
    {
        foreach($recordedEventsContainer->releaseEvents() as $event) {
            $this->recordedEvents[] = $event;
        }
    }
}
JalfResi commented 6 years ago

Thanks for the insightful response - after reflecting on your point, I agree with you that would result in "strangeness", just to cover this one case.

As a follow up, can I confirm that I am using the library correctly?

I'm using Zend Expressive, and what I'm trying to do is capture the domain events raised by my Entities as they are executed within my Command Handler. At the moment, I'm passing the EventRecorder to my command handler via the command handler factory. This is used to record the events raised by the various entities as they are called by the command handler. I'm using the above loop for each entity once I've completed any state changes. However this results is several loops for several entities as I collect up all the raised events.

The controller/action has already attached listeners and the results are processed as normal via the commandbus.

My point is that it seems a bit, I don't know if clunky is the right word, but it would be nice if my commands could implement an interface/trait pair to simplify this process somehow? not sure if I'm doing this right! Does that make sense? Am I missing something obvious?