我正在尝试在Symfony2项目中实现域驱动设计并遇到一些问题。 在阅读了一些关于Domain Models的文章后,我发现了
幸运的是,Symfony提供了活动,但这是一个问题 - 我不能从我的实体提出事件。 Symfony文档建议使用DI将调度程序注入类中,这会引发事件
http://symfony.com/doc/current/book/internals.html#passing-along-the-event-dispatcher-object
但Symfony实体是新的,不可注射。 现在我可以看到两种方式:
1)向像这样的实体提供事件Dispather
class FooEntity
{
protected $dispatcher = null;
public function setEventDispatcher(EventDispatcher $dispatcher)
{
$this->dispatcher = $dispatcher;
}
}
2)从服务中提升事件(而不是来自实体)。
这些选项看起来都不漂亮,因为在我看来他们打破了域模型的意识形态。 你能指出我正确的方向吗?
答案 0 :(得分:2)
Symfony实体,您的意思是Doctrine 2实体吗?如果是这样,您可以按以下方式在从数据库加载的新对象和旧对象上设置服务:
原型范围中的服务总是在您获得时重新创建。不是new FooEntity
,而是$container->get('foo_entity')
。
在YAML语法中,您将按如下方式定义服务:
foo_entity:
class: FooEntity
calls:
- [setEventDispatcher, [@event_dispatcher]]
scope: prototype
这将照顾新的实体。对于现有实体,您需要...
按照此处描述的方式创建一个事件监听器:
http://symfony.com/doc/current/cookbook/doctrine/event_listeners_subscribers.html
让听众听取postLoad
- 事件。将事件调度程序注入侦听器服务,并使用侦听器服务在实体上设置事件调度程序。
请记住,监听器服务将在加载任何实体后触发,而不仅仅是FooEntity,因此您需要进行类型检查。
答案 1 :(得分:2)
这里的想法是提供达到DDD范式的途径。
我不想影响@magnusnordlander的答案,我会用他所说的。
以下是对此事的一些看法:
我认为实体本身不应该拥有一切。这肯定不是DDD人会说的话。 [Doctrine2]实体应该只关注relationships(entity with different variation too< =这实际上是我被困了一段时间)和aggregate root。
Doctrine实体应该只知道如何使用自己。
但是,要获取数据或使用它,还有其他可以使用的东西:
存储库
提供帮助程序的东西是否能够获得比findBy(array('id'=>$idvalue))
快速Entity / Assocation / Annotation无法覆盖的更复杂的查找程序?方便的确是一件好事。
我个人尝试构建所有查询,并意识到EntityManager已经非常好,开箱即用。 在大多数情况下,根据我的意见:如果您可以/不使用查询或查询构建器,那就更好了。
所有的商业逻辑......
最后要注意的是,你要搜索的内容必须是基本上使控制器变薄。
FooManager (例如)是业务逻辑的地方(如果我没记错的话)。
我找到了关于此事的信息的金矿on this blog,其中包括:
Event
和如果您有任何想法,请将此答案设置为社区维基