用于自动装配服务的symfony 3标记服务

时间:2018-12-14 13:44:50

标签: symfony service autowired

我试图根据此处的文档https://symfony.com/doc/3.4/service_container/tags.html

创建一个接口,以创建可以添加到其他服务中的带标签的服务。

我创建了

之类的界面
namespace AppBundle\Model;


interface PurgeInterface {
  //put your code here
  public function purge ();
}

将定义放入service.yml:

_instanceof:
    AppBundle\Model\PurgeInterface:
        tags: ['app.purge']

并在此界面上创建服务。 控制台调试:容器显示我的服务已正确标记。

我创建了另一个服务,该服务应与带标签的服务一起使用,但这不起作用。

services.yml:

    purge_manager:
        class: AppBundle\Service\PurgeManager
        arguments: [!tagged app.purge]

该服务如下:

namespace AppBundle\Service;

use AppBundle\Model\PurgeInterface;

class PurgeManager {

  public function __construct(iterable $purgers) {
    dump($purgers);
  }
}

如果我对此进行测试,则会得到:

Type error: Too few arguments to function AppBundle\Service\PurgeManager::__construct(), 0 passed in /.....Controller.php on line 21 and exactly 1 expected

我没有尝试创建编译器遍历,因为我只是想了解为什么这样做不起作用,根据文档应该如此

预先感谢

塞巴斯蒂安

1 个答案:

答案 0 :(得分:0)

您可以在配置中使用标签,手动服务定义和_instanceof。这是Symfony的一种方式,但是需要大量的YAML编码。还有什么选择?

使用自动接线阵列

我已经回答了it here,但是您使用的大小写要短得多,我想用您的特定代码来回答。

最简单的方法是通过自动装配数组自动装配参数。

  • 没有标签
  • 支持PSR-4自动发现
  • 服务外无需编码
  • 1次编译器通过

示例

namespace AppBundle\Service;

use AppBundle\Model\PurgeInterface;

class PurgeManager
{
    /**
     * @param PurgeInterface[] $purgers
     */
    public function __construct(iterable $purgers) {
        dump($purgers);
    }
}

这也称为收集器模式

如何集成


如果存在一些不兼容的类,请在编译器遍历的构造函数中排除它们:

$this->addCompilerPass(new AutowireArrayParameterCompilerPass([
    'Sonata\CoreBundle\Model\Adapter\AdapterInterface'
]);