标记服务为私有打从第一天起就被Symfony服务容器支持。默认时,所有服务都是public的,但设置public选项为false就会令它们变为私有服务:

1
2
3
4
services:
    app.manager.user:
        class: AppBundle\Manager\User
        public: false

直觉上,你可能认为私有服务将不再被容器访问到。实际上,它们的行为略显复杂:

  • 如果一个private服务没被注入到任何其他服务中,它将被容器移除;

  • 如果一个private服务仅被注入到一个服务中,它将被行内化(inlined),其服务定义将被容器移除;

  • 如果一个private服务仅被注入到一个以上的服务中,其行为就如同public服务一样,你甚至可以通过$container->get('...')来访问到它。

最后一种行为是违反直觉的,所以我们决定在Symfony 3.2中改进private services。从现在起,一个私有服务将按照你的预期行动:

  • 通过Container::set()方法来设置或取消设置一个私有服务在Symfony 3.2中被deprecated,4.0中将不再支持;

  • 通过Container::has()方法来检查一个私有服务是否存在,在Symfony4.0中永远返回false

  • 通过Container::get()方法来请求一个私有服务在Symfony 3.2中被deprecated,4.0中将不再返回该服务;

下一步,可能在Symfony 3.2发布之前会完成,将是随机化private services的id(服务名称),以令程序仍然能够获取那些服务,而回避Symfony强加的限制条件。