在有或没有自动接线的情况下,Symfony 4 setter注入无法捆绑使用

时间:2018-08-04 16:05:15

标签: symfony dependency-injection factory autowired symfony4

我以为我完全理解了Symfony的自动装配行为,但是肯定有一些我想念的东西,希望有人能填补空白。

开头的三个问题:

  • 在主应用程序和捆绑软件中,Symfony自动装配行为是否有所不同?
  • 如果您要求Symfony自动绑定捆绑服务,它会完全忽略捆绑services.yaml文件中的服务定义吗?
  • Symfony 4中的setter注入功能是否存在已知问题?

我在使用setter注入的捆绑包中有一个服务定义,但是当我要求Symfony自动捆绑我的捆绑包服务时,甚至当我要求Symfony从自动装配中排除服务时,Symfony似乎都完全忽略了它。

我的应用程序正在使用Symfony v4.1.3

我已将Bundle包含在我的应用程序bundles.php文件中。

<?php

return [
  //... core bundles,
  Acme\\Symfony\\AcmeCustomBundle\\AcmeCustomBundle::class => ['all' => true] 
];

default Symfony应用程序services.yaml文件中,我已要求Symfony使用以下内容自动捆绑服务:

Acme\Symfony\AcmeCustomBundle\:
    resource: '../vendor/acme-symfony/custom-bundle/*'
    exclude: '../vendor/acme-symfony/custom-bundle/{Model,Tests}'

在位于services.yaml的捆绑软件../vendor/acme-symfony/custom-bundle/Resources/config/services.yaml文件中,我具有以下内容:

parameters:

services:
    Acme\Symfony\AcmeCustomBundle\Search\ConfigurationReader:
      calls:
        - method: setIndex
          arguments:
            $index: '%elasticsearch.index%'
        - method: setSchema
          arguments:
            $schema: '%elasticsearch.schema%'  

这些参数是在我的bundle扩展类中设置的(扩展了可配置扩展名),并且我已经验证了这些参数确实存在并且正在使用以下方法进行设置:

$container->setParameter('elasticsearch.index', $mergedConfigs['elasticsearch']['index']);
$container->setParameter('elasticsearch.schema', $mergedConfigs['elasticsearch']['schema']);

现在回到问题所在。即使我通过以下操作告诉Symfony不要自动装配以上服务,Symfony也不会执行setter注入:

 Acme\Symfony\AcmeCustomBundle\:
    resource: '../vendor/acme-symfony/custom-bundle/*'
    exclude: '../vendor/acme-symfony/custom-bundle/{Model,Tests,Search}'

但是我确实得到Symfony在我配置服务时

  • 关闭上述服务的自动接线
  • 使用了工厂创建服务的方法

这种方式回答了我上面的第二个问题,但我不是100%确信。尽管如此,我宁愿不必使用工厂类来解决Symfony可能存在的问题,或者我对二传手注入/自动装配的工作原理缺乏了解。

有人能看到我明显失踪的东西吗?

2 个答案:

答案 0 :(得分:3)

您可以根据需要自动连接其他方法(例如,Setters),只需使用服务中的 @required 注释即可。

/**
 * @required
 */
public function setFoo(FooInterface $foo)
{
    $this->foo = $foo;
}

Autowiring other methods

答案 1 :(得分:0)

首先,捆绑在一起的自动装配不是最佳实践的一部分。您必须显式定义要共享的捆绑包的服务,并在xml中进行。

现在,可以这么说,autowire的作用是在类的构造函数中连接服务,尝试自动解析它们。它不执行setter注入。

您需要做的是配置一个自动配置条目。在捆绑扩展类中,您可以执行以下操作:

$container->registerForAutoconfiguration(ConfigurationReader::class)
    ->addMethodCall('setIndex', ['%elasticsearch.index%'])
    ->addMethodCall('setSchema', ['%elasticsearch.schema%']);

现在,这实际上是要与接口或抽象类一起使用,而不是与具体实现一起使用。但是,如果您要自动配置服务,那是可以做的。

我的建议是,如果您要重用此捆绑包,请在xml中显式定义服务。自动装配适用于您的业务逻辑和服务。