Symfony 依赖注入:注入一个新的类实例

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个回答

7

2

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

<?php

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

    app.class_factory: class: ClassFactory

  • 注入新类,如下所示:

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

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


0

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

在普通应用程序中,使用当前Symfony版本(3.4+)时实际上并不是一个问题,因为所有服务默认都是私有的,所以服务容器会自动注意到是否只使用了一次私有服务,然后将其内联(因此不使用名称),从而生成与在PHP中定义没有名称的服务完全相同的服务容器代码。

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


0

1
这意味着在配置文件中添加大量仅使用一次的服务,这些服务没有依赖关系,不应该在容器构建之外使用。在这种情况下,我宁愿使用PHP构建容器的这部分。 - spdionis
如果它不应该在容器外部使用,那么它们应该被标记为“public=false”(私有)。你必须把它们放进一个容器里,这就是它的工作原理 :) - Wouter J
1
我只是害怕最终会有100个服务。 - spdionis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接