Symfony Dependency Injection注入了新的类实例

时间:2014-02-20 15:00:13

标签: php symfony dependency-injection yaml symfony-components

我正在使用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 个答案:

答案 0 :(得分:5)

范围是deprecated since 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

答案 1 :(得分:1)

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

<?php

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

    app.class_factory: class:ClassFactory

  • 注入新类之后
  • 参数:['@ = service(“app.class_factory”)。create(“Monolog \ Logger”)']

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

答案 2 :(得分:0)

是的,您注入的所有课程都应该是服务。您可以为他们提供prototype的范围,以便在每次请求时创建新实例。

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

答案 3 :(得分:0)

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

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

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