Contributed by
Ryan Weaver
in #22234.

在Symfony 3.3中,配置服务非常简单 ,这得益于以下全新配置选项:

  • _defaults: 向在给定文件中定义的服务,定义 public, tagsautowire 选项;
  • _instanceof: 基于服务自身的类,来定义服务的默认配置(如,添加 twig.extension 标签到任何实现了 Twig_ExtensionInterface 接口的服务)。

带来这种简化的即是 autoconfigure 选项,有些像 _instanceof 的自动版本。如果开启之,此选项将基于服务所实现的类,来添加一些默认的配置信息。

我们假设,你希望自动添加标签到你的security voters中:

1
2
3
4
5
6
7
8
9
services:
    _defaults:
        autowire: true

    _instanceof:
        Symfony\Component\Security\Core\Authorization\Voter\VoterInterface:
            tags: [security.voter]

    AppBundle\Security\PostVoter: ~

现在问你自己,你是否正在用一个实现了 VoterInterface 的类来注册一个服务,你是否某些时候不希望该服务被打上 security.voter 标签?换言之,一个实现了 VoterInterface 接口的服务只能是一个security voter,除非你执意要做一件诡异之事。

在同一例子中像下面这样使用 autoconfigure 选项:

1
2
3
4
5
6
services:
    _defaults:
        autowire: true
        autoconfigure: true

    AppBundle\Security\PostVoter: ~

这能够工作是因为被开启的每一个bundle都有机会添加一或多个自动的 _instanceof 定义。当然,我们目前对所有常见的Symfony服务: 命令(commands), 表单类型(form types), 事件监听(event subscribers)等开启了此选项。

并非魔法

无论何时当我们引入一个全新的功能以实现服务的自动化配置时,某些开发者会随即怀疑这可能是“魔法”。对我们来说,“魔法”意味着在你并未显式请求的时候发生了一些事。若是魔法就很糟糕,因为它会令人崩溃,而且存在难于调试等问题。

然而,这一功能将不会工作,除非你在配置文件中显式地包容了 autoconfigure 选项。此外,它只会应用到那些定义在“同一文件”之中的服务,即你引入 autoconfigure 的那个配置文件中的服务之上,以便抵消副作用。简言之,这并非魔法,只是自动化(automation)。