8

我正在使用 symfony/dependency-injection 组件(注意:不使用完整的堆栈框架)

注册新服务时,我想在构造函数中注入一个类的新实例。例子:

$container->register('session', 'Vendor\Core\Session')
    ->addArgument(new PhpBridgeSessionStorage());

该示例运行良好,但如果我想使用 yml 文件来定义此服务怎么办?就像是:

services:
  session:
    class: Vendor\Core\Session
    arguments: [ new Class\To\Inject ]

我是否被迫将 Class\To\Inject 定义为新服务?还是创建一个服务工厂?

4

4 回答 4

6

自 2.8 起,范围已被弃用。改为使用shared: false

http://symfony.com/doc/current/cookbook/service_container/shared.html

services:
  session:
    class: Vendor\Core\Session
    arguments: [ "@inject.me" ]

  inject.me:
    class: Class\To\Inject
    shared: false
于 2016-05-27T07:03:16.090 回答
2

我现在这个问题已经很老了,但是这里有一个技巧,您可以使用它来避免将每个简单的类定义为服务,定义一个“工厂类”服务,该服务接收要创建的类作为参数,然后通过“表达式语言”注入作为参数:

<?php

final class ClassFactory
{
   public static function create($class, array $arguments = [])
   {
     return new $class($arguments);
   }
}
  • 创建新服务

    app.class_factory:类:ClassFactory

  • 在注入这样的新类之后:

    参数:['@=service("app.class_factory").create("Monolog\Logger")']

对于 Symfony >=2.8,您还可以查看“自动接线”功能 -> http://symfony.com/blog/new-in-symfony-2-8-service-auto-wiring

于 2017-01-09T10:16:02.473 回答
0

是的,您注入的所有类都应该是服务。您可以给他们一个范围,prototype以便在每次请求时创建一个新实例。

有关更多信息,请参阅:http ://symfony.com/doc/current/cookbook/service_container/scopes.html

于 2014-02-20T15:19:43.167 回答
0

我自己一直在为一个只需要为其他服务创建一些值对象(服务)的库寻找这个答案,我觉得与定义相比,YAML 中的所有这些服务(具有长唯一名称)都在污染服务配置在 PHP 中没有服务名称的值对象。

在常规应用程序中,当使用所有服务默认为私有的当前 Symfony 版本(3.4+)时,这实际上不是问题,因为如果私有服务仅使用一次然后内联它,服务容器会注意到自己(因此名称将不会被使用),从而产生与您在 PHP 中定义没有名称的服务时完全相同的服务容器代码。

因此,只要您将所有服务声明为私有(或使用 Symfony 3.4+ 中的默认值),它们就会相应地进行优化(如果不使用则将其删除)。

于 2019-04-02T09:01:43.330 回答