I'm trying to implement Domain Driven Design in my Symfony2 project and experience some problems. After reading some articles on Domain Models I found, that
Luckily, Symfony provides Events, but here is a problem - I can't raise event from my entity. Symfony documentation suggects to use DI to inject the dispatcher into the class, that raises Event
http://symfony.com/doc/current/book/internals.html#passing-along-the-event-dispatcher-object
But Symfony Entities are newable, not injectable. Right now I can see two ways:
1) Provide Event Dispather to Entity like this
class FooEntity
{
protected $dispatcher = null;
public function setEventDispatcher(EventDispatcher $dispatcher)
{
$this->dispatcher = $dispatcher;
}
}
2) Raise Events from the service(not from the Entity).
None of this options look pretty, because it seems to me that they break Domain Model ideology. Can you point me in the right direction, please.
The idea of this here is to give paths to attain the DDD paradygm.
I do not want to shadow over @magnusnordlander answer, I will apply what he says.
Here is some of observations on the matter:
I think that the Entity itself should not have everything. It is sure not what the DDD people would say anyway. The [Doctrine2] Entity should only take care of the relationships (an entity with different variation too <= This is actually a thing that I was stuck for a while) and the aggregate root.
The Doctrine entity should only know about how to work with itself.
But, to Get Data or work with it, there is other stuff that you can use:
Repository
Is the thing that provides helpers to get your more sophisticated finders than what a quick findBy(array('id'=>$idvalue))
would do (and that the Entity/Assocation/Annotation cannot cover) and is indeed a great thing to have handy.
I personally tried to build all queries, and realized the EntityManager is already very good, out of the box. In most case, to my opinion: If you can /not/ use query or query builder, the better.
Business logic in all that...
Last thing on note, what you would be searching for must be to basically thin the Controller.
FooManager (for example) is where (if I am not mistaken) the business logic go.
I found a goldmine of information on that matter on this blog that covers:
Event
withIf you have any ideas, to augument, I set this answer as a Community Wiki
By Symfony entities, do you mean Doctrine 2 entities? If so, you can set services on both new objects and old objects that are loaded from the database in the following manner:
Services in the prototype scope are always recreated when you get them. Instead of doing new FooEntity
you would do $container->get('foo_entity')
.
In the YAML syntax you would define the service as follows:
foo_entity:
class: FooEntity
calls:
- [setEventDispatcher, [@event_dispatcher]]
scope: prototype
This will take care of new entities. For existing entities you need a...
Create an event listener, in the manner described here:
http://symfony.com/doc/current/cookbook/doctrine/event_listeners_subscribers.html
Have the listener listen for the postLoad
-event. Inject the event dispatcher into the listener service, and use the listener service to set the event dispatcher on the entity.
Bear in mind that the listener service will fire after loading any entity, not just the FooEntity, so you'll need to do a type check.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With