Symfony:在服务中显式定义容器

Symfony:在服务中显式定义容器,symfony,dependency-injection,Symfony,Dependency Injection,更新后,我有以下建议: Since symfony/dependency-injection 5.1: The "Symfony\Component\DependencyInjection\ContainerInterface" autowiring alias is deprecated. Define it explicitly in your app if you want to keep using it. It is being referenced by the

更新后,我有以下建议:

Since symfony/dependency-injection 5.1: The "Symfony\Component\DependencyInjection\ContainerInterface" autowiring alias is deprecated. Define it explicitly in your app if you want to keep using it. It is being referenced by the "App\Service\ImportService" service.
这是我的导入服务:

<?php

namespace App\Service;

use Symfony\Component\DependencyInjection\ContainerInterface;

class ImportService
{
    private $doctrine;
    private $em;

    public function __construct(ContainerInterface $container)
    {
        $this->doctrine = $container->get('doctrine'); //needed for database queries
        $this->em = $this->doctrine->getManager(); //needed for database queries
    }

    /** more methods here **/

}

我刚刚创建了一个新的5.1应用程序,没有得到折旧。Symfony确实在阻止注入全局容器。因此,我对它被贬值并不感到惊讶

要修复该消息,只需显式定义ContainerInterface别名:

# services.yml or yaml 
services:
    Symfony\Component\DependencyInjection\ContainerInterface: '@service_container'
这应该能奏效。然而,由于您似乎要迁移到5.1,那么您应该开始重构代码,只注入特定类需要的内容。这不是强制性的,但会使您避免后续问题:

class ImportService
{
    private $em;

    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em
    }

您必须在service.yaml中定义“@service\u container”参数

# services.yml or yaml 
services:
  Symfony\Component\DependencyInjection\ContainerInterface: '@service_container'
  
  Namespace\ImportService:
    arguments:
      - '@service_container'

然后,您可以使用ContainerInterface作为构造函数参数。

虽然使用注入容器的其他答案可以作为一个快速解决方案,但与此相反,从PHP代码中删除所有容器使用

恕我直言,这将在未来变得越来越严格,因此您必须返回代码并重构它

重构到依赖注入 如果您想让您的代码经得起未来的考验,请重构到构造函数注入:

<?php

namespace App\Service;

use Doctrine\DBAL\Connection;
use Doctrine\ORM\EntityManagerInterface;

final class ImportService
{
    private Connection $connection;

    private EntityManagerInterface $entityManager;

    public function __construct(
        Connection $connection,
        EntityManagerInterface $entityManager
    ) {
        $this->connection = $connection;
        $this->entityManager = $entityManager;
    }

    /** more methods here **/
}

正如最初的答案所指出的,正确的方法是只注入您真正需要的服务

但是,如果您正在扩展现有代码,并且现有代码随着新的更新而更改,并且您希望允许向后兼容,那么使用
容器接口
有时会更容易、更有效

由于一些开发人员也更喜欢XML而不是YAML,以下是两种解决方案:

services.yml(如果使用yaml)

服务:
Symfony\Component\DependencyInjection\ContainerInterface:“@service\u container”
services.xml(如果使用xml)



第一种方法可能会解决通知问题,但只会将问题解决。最好重构到ConstructCor注入,这是因为Symfony 3.3/3.4此解决方案仅适用于PHP7.4及更高版本。“类型化属性仅在PHP7.4中可用”您可以在PHP7.3中使用doctypes,效果相同。我只是说您的文档化解决方案是“类型化属性”,这些仅在PHP7.4及更高版本中可用。对于使用旧版本PHP的用户,这将导致语法错误。来源:PHPStorm和。当然,您可以将PHP7.3与@var doc type一起使用