将依赖注入容器传递给静态方法

时间:2016-01-05 14:10:03

标签: php symfony

我有一些Legacy课程。 许多类都使用Factory Class进行实例化。

还有一个Singleton-Class。

将来我想用DIC完全替换它们。 目前,代码库要做到这一点很大。

现在我的目标是将DI-Container注入Singleton类实例化的每个Service中。 Singleton类有一个带有此签名的静态方法。

final class Singleton
{
  private static $singletonCache = array();

  public static function getInstance($namespace, $className)
  {
  }
}

我想检查这个函数的内部:

$instance = new $className();

if($instance instanceof ContainerAwareInterface)
{
  // TODO: how do we get the container here
  $instance->setContainer($container);
}

但是我怎样才能最好地将容器放入我的“单件类”中,这只是静态调用?

3 个答案:

答案 0 :(得分:4)

另一种方法是在需要时全局访问容器:

public static function getInstance($namespace, $className)
{
  $container = $_GLOBAL['kernel']->getContainer();
}

当然,这种方法有很多不妥之处,但只要你过渡到那就足够了。

答案 1 :(得分:2)

在引导代码的早期某个地方,但在实例化容器之后,您可以将容器传递给您的单例类:

Singleton::setContainer($container);

它会将容器存储在静态属性中:

final class Singleton
{
    // ...

    private static $container;

    public static function setContainer(ContainerInterface $container)
    {
        self::$container = $container;
    }
}

然而,正如您在单例类的示例中所了解到的那样,所有全局状态都会给您带来麻烦。传递容器(并使用ContainerAware)是需要避免的。通过将容器传递给您的服务,您可以让它们依赖于整个服务世界。只通过你真正需要的合作者,它更干净。它也更容易测试。

答案 2 :(得分:1)

this answer中提出了另一种解决方案,与该问题的其他答案几乎相同,只是使用了global关键字而不是$_GLOBAL数组来访问内核对象。

public static function getInstance($namespace, $className)
{
  global $kernel;
  $container = $kernel->getContainer();
}