首页 文章

symfony域事件

提问于
浏览
6

我正在尝试在我的Symfony2项目中实现域驱动设计并遇到一些问题 . 在阅读了一些关于Domain Models的文章后,我发现了

  • 我应该将所有业务逻辑放入我的域模型(实体)中 .

  • 需要完成并且不属于域逻辑的应用程序级别的东西会被域事件触发(发送电子邮件,将一些消息放入队列等)

幸运的是,Symfony提供了活动,但这是一个问题 - 我不能从我的实体提出事件 . Symfony文档建议使用DI将调度程序注入类中,从而引发Event

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)从服务(而不是实体)提升事件 .

这些选项看起来都不是很漂亮,因为在我看来他们打破了域模型的意识形态 . 请你指点我正确的方向 .

2 回答

  • 2

    这里的想法是提供达到DDD范式的途径 .

    我不想影响@magnusnordlander的答案,我会用他所说的 .

    以下是对此事的一些看法:

    我认为实体本身不应该拥有一切 . 这肯定不是DDD人会说的话 . [Doctrine2]实体应该只处理relationshipsentity with different variation too <=这实际上是我被困了一段时间)和aggregate root .

    Doctrine实体应该只知道如何与自己合作 .

    但是,要获取数据或使用它,还可以使用其他东西:

    Repository

    提供帮助器的东西是否比快速 findBy(array('id'=>$idvalue)) 所能提供的更复杂的查找器(并且Entity / Assocation / Annotation无法覆盖)并且确实是一个方便的好东西 .

    我个人试图构建所有查询,并意识到EntityManager已经非常好,开箱即用 . In most case, to my opinion :如果你能/不能/使用查询或查询构建器,那就更好了 .

    Business logic in all that...

    最后要注意的是,你要搜索的内容必须是基本上瘦控制器 .

    FooManager (例如)是业务逻辑去的地方(如果我没有记错的话) .

    我找到了关于此事的信息的金矿on this blog,其中包括:

    如果您有任何想法,请将此答案设置为社区Wiki

  • 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 -event . 将事件调度程序注入侦听器服务,并使用侦听器服务在实体上设置事件调度程序 .

    请记住,监听器服务将在加载任何实体后触发,而不仅仅是FooEntity,因此您需要进行类型检查 .

相关问题