将配置从 service.yaml 移动到 Symfony5 中的另一个文件

Iva*_*vić 2 php yaml symfony symfony5

我的config/service.yaml包含多个配置庞大的服务。现在,我想将该服务的配置移至单独的文件中。

我尝试这样做:

在......的最后service.yaml

imports:
   - { resource: 'packages/custom_service.yaml' }
Run Code Online (Sandbox Code Playgroud)

config/packages/custom_service.yaml:

services:
    App\Service\CustomService:
        arguments:
            $forms:
                - location: 'room1'
                  id: 43543
                - location: 'room2'
                  id: 6476546
                - location: 'room3'
                  id: 121231
        ...
Run Code Online (Sandbox Code Playgroud)

src/Service/CustomService.php:

    /**
     * @var array
     */
    protected $forms;

    public function __construct(array $forms)
    {
        $this->forms = $forms;
    }
Run Code Online (Sandbox Code Playgroud)

但是当我尝试在某些控制器中自动连接时,我收到此错误:

Cannot resolve argument $customService of "App\Controller\CustomController::customAction()": Cannot autowire service "App\Service\CustomService": argument "$forms" of method "__construct()" is type-hinted "array", you should configure its value explicitly.
Run Code Online (Sandbox Code Playgroud)

但是如果我删除类型提示,那么我会收到此错误:

Cannot resolve argument $customService of "App\Controller\CustomController::customAction()": Cannot autowire service "App\Service\CustomService": argument "$forms" of method "__construct()" has no type-hint, you should configure its value explicitly.
Run Code Online (Sandbox Code Playgroud)

Cer*_*rad 5

其他两个答案部分正确,但并不能涵盖所有内容。

首先,每当您决定需要多个自动装配服务文件时,您都必须小心,给定的服务只能由一个文件自动装配。否则 Symfony 将多次尝试定义服务并且通常会失败。有多种方法可以实现此目的,但最直接的方法是显式排除 config/services.yaml 文件中的任何自定义服务:

# config/services.yaml
parameters:

imports:
    - { resource: 'services/custom_service.yaml' }

services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.

    # makes classes in src/ available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    App\:
        resource: '../src/'
        exclude:
            - '../src/Service/CustomService.php' # ADD THIS
            - '../src/DependencyInjection/'
            - # the rest of the default excludes
Run Code Online (Sandbox Code Playgroud)

这样就可以跳过主配置文件中的 CustomService.php 了。

其次,请注意,在上面的文件中,我从 config/services 而不是 config/packages 加载了 custom_service.yaml 文件。这些包实际上是为特定于捆绑包的配置而保留的。默认情况下会加载其中的每个文件。将服务文件放在那里可能会或可能不会起作用,但它肯定会改变事物的加载顺序并可能导致问题。因此,为自定义服务创建一个目录并使用它。

您还需要在每个服务文件中重复 _defaults 部分,因为 _defaults 被认为是特定于文件的。也许有点痛苦,但事实就是这样:

# config/services/custom_service.yaml

services:
  _defaults:
    autowire: true
    autoconfigure: true

  App\Service\CustomService:
    arguments:
      $forms:
        -
            location: 'room1'
            id: 43543
        -
            location: 'room2'
            id: 6476546
        -
            location: 'room3'
            id: 121231
Run Code Online (Sandbox Code Playgroud)

另请注意,您的 yaml 数组语法很混乱。可能只是复制/粘贴问题。

那应该可以了。