代码之家  ›  专栏  ›  技术社区  ›  Sebastian Mery

symfony 3自动布线服务中使用的标签服务

  •  1
  • Sebastian Mery  · 技术社区  · 7 年前

    我试图创建一个接口来创建标记的服务,这些服务可以根据这里的文档注入到另一个服务中 https://symfony.com/doc/3.4/service_container/tags.html

    我创建了一个界面,比如

    namespace AppBundle\Model;
    
    
    interface PurgeInterface {
      //put your code here
      public function purge ();
    }
    

    将定义放入服务中。yml:

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

    并在此接口上创建服务。 控制台调试:容器将我的服务显示为正确标记。

    我创建了另一个服务,它应该与标记的服务一起工作,但这不起作用。

    服务。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 回复  |  直到 7 年前
        1
  •  0
  •   Tomas Votruba    7 年前

    您可以使用标签、手动服务定义和 _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'
    ]);