【问题标题】:Symfony ServiceSubscriber aliased serviceSymfony Service Subscriber 别名服务
【发布时间】:2020-02-07 08:19:29
【问题描述】:

在 Symfony 中,您可以使用相同的接口 DI 不同的服务,如下所示:

public function __construct(ServiceInterface $serviceOne, ServiceInterface $serviceTwo)

但是如何使用ServiceSubscriberInterface 以同样的方式实现这一点?

public static function getSubscribedServices()
{
    return [
        'commandBus' => MessageBusInterface::class . ' $commandBus',
        'queryBus' => MessageBusInterface::class . '$queryBus',
    ];
}

这些是我已经检查过的资源: https://symfony.com/doc/current/service_container/service_subscribers_locators.html https://symfony.com/doc/current/messenger/multiple_buses.html

【问题讨论】:

  • 您的第一个陈述略有错误,这种情况很少见,据我所知,具体到 messenger 组件,它关心 var 名称。这也是我假设的原因,这对于ServiceSubscriberInterface 来说并不那么简单。但是,我假设您有一个特定的用例,如果您至少提供一些有关它的详细信息,也许可以解决该用例。
  • docs 中,他们展示了如何使用相同的 MessageBusInterface DI $queryBus 和 $commandBus。所以我假设你也可以将它与服务定位器一起使用。
  • 是的,但这是在 messenger 组件中的特殊编译器传递中完成的。对于这种特定情况,没有编译器通道可以处理 ServiceSubscriberInterfaces。如果你描述一下用例是什么,那真的很有帮助,因为有很多用例,而且大多数都有不同的方法。
  • 啊哈!我的用例是我有一个需要几个服务的抽象处理程序,并且孩子可以(可选地)包含它需要的服务。我喜欢this 模式。
  • 我以为 ServiceSubscriberInterface 使用同一个容器来获取服务?带有 ServiceSubscriberInterface 的服务被延迟加载,因此使用的容器应该具有来自 Messenger 编译器传递的已编译的 $queryBus 和 $commandBus。对吗?

标签: php symfony dependency-injection


【解决方案1】:

我很怀疑,但显然你是对的,你可以多次使用一个界面,但必须做一些work,基本上信使组件会做这样的事情,我猜(我没有广泛检查 - 更新:我试图找到这个,但到目前为止没有成功......)。

这就是我假设构造函数 DI 有效的原因。 ServiceSubscriberInterface::getSubscribedServices() 是used in a similar way: 具体来说,该数组的 key 被假定为别名或类名或接口名或...但显然,这并不是为您提供索引服务数组的好方法,因为它有意义。

所以,我认为,只需删除阵列的键就可以很好地完成这项工作。或者,您可以通过运行bin/console debug:container MessageBusInterface 来使用MessageBusInterfaces 的实际服务名称,这有望返回提供该接口的服务别名列表...或者您可能必须查看完整列表...

更新:正如Snek在聊天中正确指出的那样,值必须是FQCN,导致我假设键应该是接口+ varname,而值只是接口)

为了进一步使用ServiceSubscriberInterface,您仍然需要在您的类中添加一个服务定位器(如in the comment 所示),然后才能提供服务。但是,我想知道信使组件是否不会提供类似的按名称检索特定总线的方法...

【讨论】:

    【解决方案2】:

    所以经过一些测试并在@Jakumi 的帮助下。发现数组key可以用来解析别名服务,如下。

    public static function getSubscribedServices()
    {
        return [
           'commandBus' => MessageBusInterface::class,
           'queryBus' => MessageBusInterface::class,
        ];
    }
    

    在我的 messenger.yaml 中:

    framework:
      messenger:
        default_bus: 'command.bus'
        buses:
          command.bus:
            // stuff
          query.bus:
            // stuff
    

    【讨论】:

    • 我想知道...不应该是getSubscribedServices中的'command.bus''query.bus'吗?
    • 不。因为 messenger 的编译器通过使它们成为驼峰式大小写。 See screenshot
    • 这太不直观了...感谢您的宝贵时间;o)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 2021-01-29
    • 1970-01-01
    • 2017-01-13
    • 1970-01-01
    • 2019-06-28
    • 2018-01-15
    相关资源
    最近更新 更多