Symfony domain event

I am trying to implement Domain Driven Design in my Symfony2 project and am experiencing some problems. After reading some articles on domain models, I found that

  • I have to put all the business logic in my domain models (objects).
  • The application level, which must be executed and does not belong to the domain logic, is triggered using domain events (sending emails, sending some messages to the queue, etc.).

Fortunately, Symfony provides events, but here's the problem - I cannot fire an event from my object. Symfony documentation suggests using DI to inject a dispatcher into a class that raises an event

http://symfony.com/doc/current/book/internals.html#passing-along-the-event-dispatcher-object

But Symfony Entities are new, not injectable. Now I see two ways:

1) Provide a Dispather event for Entity like this

class FooEntity { protected $dispatcher = null; public function setEventDispatcher(EventDispatcher $dispatcher) { $this->dispatcher = $dispatcher; } } 

2) Raise events from a service (not from Entity).

None of these options look attractive, because it seems to me that they violate the ideology of the Domain Model. Can you point me in the right direction, please.

+6
source share
2 answers

The idea here is to provide ways to achieve the DDD paradigm.

I don't want to obscure @magnusnordlander's answer, I will apply what he says.

Here are a few notes on this:

I think that the essence itself should not have everything. This is definitely not what DDD people will say anyway. The body of [Doctrine2] should only care about relationships (an object with different variations <= This is actually what I stuck for a while) and the cumulative root .

The essence of the doctrine should know only how to work with oneself.

But to get data or work with it, there are other things you can use:

Repository

This is what provides helpers to get more sophisticated crawlers than what quick findBy(array('id'=>$idvalue)) (and that Entity / Assocation / Annotation can't cover) and a really great thing to to have comfortable.

I personally tried to create all the queries and realized that the EntityManager is already very good, out of the box. In most cases, in my opinion,. If you can / don't use / use the query or query builder, all the better.

The business logic in all of this ...

The last thing you noticed, what you were looking for, should be to basically remove the controller.

FooManager (for example) is where (if I'm not mistaken) the business logic goes.

In this blog, I found a goldmine of information that covers:

If you have any ideas to complement, I asked this answer as a Community Wiki

+2
source

By Symfony objects, do you mean Doctrine 2 objects? If so, you can install services for both new objects and old objects loaded from the database as follows:

Prototype Service

Prototype services are always recreated when you receive them. Instead of new FooEntity you would do $container->get('foo_entity') .

In the YAML syntax, you must define the service as follows:

 foo_entity: class: FooEntity calls: - [setEventDispatcher, [@event_dispatcher]] scope: prototype 

This will take care of new facilities. For existing facilities you need ...

Load Load Event Listener

Create an event listener as described here:

http://symfony.com/doc/current/cookbook/doctrine/event_listeners_subscribers.html

Ask the listener to listen to postLoad -event. Add the event dispatcher to the listener service and use the listener service to install the event dispatcher in the entity.

Keep in mind that the listener service will fire after loading any object, not just FooEntity, so you need to do a type check.

+2
source

Source: https://habr.com/ru/post/900963/


All Articles