php-ddd icon indicating copy to clipboard operation
php-ddd copied to clipboard

Using the Symfony Event Dispatcher for Application Events

Open webdevilopers opened this issue 8 years ago • 6 comments

Here is a question by @chrisguitarguy that came to mind before when I was using the @SimpleBus by @matthiasnoback:

Do you hide your event emiting code behind an interface you own in your #php apps? Why or why not? By that, I mean instead of using Symfony's event dispatcher directly you create an interface and a Symfony adapater implenting it.

  • https://twitter.com/chrisguitarguy/status/793100909416886272

The @SimpleBus has a SmyfonyBridge:

  • https://github.com/SimpleBus/SymfonyBridge

And for the RabbitMQBundle too:

  • https://github.com/SimpleBus/RabbitMQBundleBridge

I remember trying out the tutorial:

  • http://php-and-symfony.matthiasnoback.nl/2015/01/collecting-events-and-the-events-aware-command-bus/

But I think I didn't figure out why the events did not actually fire.

Does anybody have a working example or code on github?

webdevilopers avatar Nov 01 '16 08:11 webdevilopers

The use case I had in mind for the question was a bit different than the simple bus example. I have a set of distributed workers that all tackle on task in parallel. When a worker completes its bit of the task, there's a good chance that it may be the last bit of the overall task as a whole. If that's the case, the worker should emit an event. This is a domain event saying that something happens and it is emitted from a service object, not a command handler.

In the end I decided to try out having an internal event emitter interface, but it's a super leaky abstraction. Strikes the right balance for service that need to emit events only and don't care how they are handled, though.

use Symfony\Component\EventDispatcher\EventDispatcherInterface;

// this has a different name in the real application
interface DomainEvent
{

}

interface Emitter
{
    public function emit(DomainEvent $event);
}

final class SymfonyEmitter implements Emitter
{
    /**
     * @var EventDispatcherInterface
     */
    private $dispatcher;

    public function __construct(EventDispatcherInterface $dispatcher)
    {
        $this->dispatcher = $dispatcher;
    }

    /**
     * {@inheritdoc}
     */
    public function emit(CrmEvent $event)
    {
        $this->dispatcher->dispatch(get_class($event), $event);
    }
}

chrisguitarguy avatar Nov 01 '16 13:11 chrisguitarguy

I don't know if you're waiting for my opinion, but here we go anyway: I don't like to use the Symfony event dispatcher for my domain events (because of the Event base class stuff and the way event listeners can stop propagation, have a priority, etc.), so I added a very simple dispatcher to SimpleBus, which has no requirements whatsoever for the contract of the objects involved.

matthiasnoback avatar Nov 02 '16 08:11 matthiasnoback

Thanks @matthiasnoback for your feedback!

I havn't checked it yet but I think there is another downside of the @symfony event dispatcher since it only allows passing a single object instead of multiple primitive args - e.g. comming from a Command or DTO. Is that right?

webdevilopers avatar Nov 02 '16 10:11 webdevilopers

That's right, but I think it's always a sensible thing to dispatch an object anyway.

matthiasnoback avatar Nov 02 '16 11:11 matthiasnoback

I saw your example how to inject the event_recorder into your Application Handler here @matthiasnoback :

  • http://simplebus.github.io/SymfonyBridge/doc/event_bus_bundle.html

But as mentioned I didn't understand how / where to put my middleware - or how to use it with a Symfony Bridge. For now I could release the events inside my Controller which is very ugly.

Besides I would prefer to raise the event inside my DomainModel. - But without using Doctrine. Is this possible with your Bus / Bundles?

Maybe @mablae had something like this running already?

webdevilopers avatar Dec 13 '16 11:12 webdevilopers

Related:

  • https://github.com/SimpleBus/MessageBus/issues/18 @mseshachalam

webdevilopers avatar Jan 18 '17 18:01 webdevilopers