Symfony4:将服务注入控制器 __construct(构造函数)

Symfony4: inject service into controller __construct (constructor)

我在访问我的一个控制器的构造函数中的注入服务时遇到问题。

根据 http://symfony.com/doc/current/service_container/injection_types.html 我相信我已经正确地完成了注入,但是当我尝试从控制器加载视图时,出现以下错误:

Argument 1 passed to Regions\AnalyticsBundle\Controller\PatternsController::__construct()
must be an instance of Regions\AnalyticsBundle\Controller\PatternCacheService, instance of
Regions\AnalyticsBundle\Service\PatternCacheService given, called
in /var/tmp/symfony/cache/dev/ContainerLoHUcSH/getPatternsControllerService.php on line 9

似乎错误表明构造函数中的类型提示正在尝试使其在 *\Controller\* 命名空间而不是 *\Services\* 命名空间中查找实例 - 我做错了什么或没看到这里?

我的设置详情如下...

Symfony 4.1.0,PHP7.2.5

services.yaml

services:
    ...

    pattern_cache_service:
        class: Regions\AnalyticsBundle\Service\PatternCacheService
        public: true

    Regions\AnalyticsBundle\Controller\PatternsController:
        arguments: ['@pattern_cache_service']

控制器:

namespace Regions\AnalyticsBundle\Controller;

class PatternsController extends BaseController
{

    private $pcs;

    public function __construct(PatternCacheService $pcs)
    {
        $this->pcs = $pcs;
    }
}

您在您的控制器中忘记了一个 use,使得 PHP 认为您的服务与您的控制器在同一个命名空间中。

<?php

namespace Regions\AnalyticsBundle\Controller;

use Regions\AnalyticsBundle\Service\PatternCacheService;

class PatternsController extends BaseController
{

    private $pcs;

    public function __construct(PatternCacheService $pcs)
    {
        $this->pcs = $pcs;
    }
}

这实际上是作为您的错误消息的一部分提出的

Argument 1 passed to Regions\AnalyticsBundle\Controller\PatternsController::__construct() must be an instance of Regions\AnalyticsBundle\Controller\PatternCacheService

当您期望控制器需要 Regions\AnalyticsBundle\Service\PatternCacheService

的实例时

在命名空间 Regions\AnalyticsBundle\Controller 中找不到 class PatternCacheService

添加导入:

<?php

namespace Regions\AnalyticsBundle\Controller;

use Regions\AnalyticsBundle\Service\PatternCacheService;

class PatternsController extends BaseController
{

    private $pcs;

    public function __construct(PatternCacheService $pcs)
    {
        $this->pcs = $pcs;
    }
}

参考

  1. 您不需要 pattern_cache_service 的服务定义。如果设置了 autowire: true,它应该自动连接您的服务。
  2. PatternCacheService 应该是 private 因为您不想从容器内访问它。建议练习!
  3. 您也不需要 PatternsController 的服务定义。

注意:你不应该在 Symfony 4 中使用 "bundles" 所以我会去掉 AnalyticsBundle.

注意:更好地组织您的配置文件,如下所示:Organising route, service and parameter configuration files in symfony 4 applications

这应该足够了:

services.yaml

services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: false

    App\:
        resource: '../src/*'
        exclude: '../src/{Entity,....so on .....,Kernel.php}'

    App\Controller\:
        resource: '../../src/Regions/AnalyticsBundle/Controller'
        tags: ['controller.service_arguments']

模式控制器

namespace Regions\AnalyticsBundle\Controller;

use Regions\AnalyticsBundle\Service\PatternCacheService;

class PatternsController
{
    private $pcs;

    public function __construct(PatternCacheService $pcs)
    {
        $this->pcs = $pcs;
    }
}