简体   繁体   English

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

[英]Pass Dependency Injection Container to static method

I have some Legacy classes.我有一些传统课程。 Many classes are instantiated using a Factory Class.许多类是使用工厂类实例化的。

There is also a Singleton-Class.还有一个单例类。

In the future I want to replace them completely with the DIC.将来我想用 DIC 完全取代它们。 For the moment the codebase is to large to do this.目前代码库很大,无法做到这一点。

Now my goal is to inject the DI-Container into every Service instantiated by the Singleton class.现在我的目标是将 DI-Container 注入到 Singleton 类实例化的每个服务中。 The Singleton class has a static method with this signature. Singleton 类有一个带有此签名的静态方法。

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

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

inside of this function I want to check for:在此函数内部,我想检查:

$instance = new $className();

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

But how can I best get the container inside of my "singleton class", which is only called statically?但是我怎样才能最好地获得我的“单例类”中的容器,它只被静态调用?

Another approach is to access the container globally when you need it:另一种方法是在需要时全局访问容器:

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

Of course there are sorts of things wrong with this approach but as long as you are transitioning then it's enough to get by.当然,这种方法有一些问题,但只要你正在过渡,就足够了。

Somewhere early in your bootstrapping code, but after the container is instantiated, you can pass the container to your singleton class:在引导代码的早期某处,但在实例化容器之后,您可以将容器传递给单例类:

Singleton::setContainer($container);

It would store the container in a static property:它将容器存储在静态属性中:

final class Singleton
{
    // ...

    private static $container;

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

However , as you learned on the example of your singleton class, all global state gives you is headaches.但是,正如您在单例类的示例中了解到的那样,所有全局状态都让您头疼。 Passing the container around (and using ContainerAware) is something to avoid.传递容器(并使用 ContainerAware)是要避免的事情。 By passing the container to your services you're making them rely on the whole world of services.通过将容器传递给您的服务,您让它们依赖于整个服务世界。 It's cleaner to only pass collaborator you actually need.只传递您实际需要的协作者会更干净。 It's also far easier to test.它也更容易测试。

Another solution is presented in this answer , which is pretty much the same as the other answer to this question, just using the global keyword instead of the $_GLOBAL array to access the kernel object.此答案中提供了另一种解决方案,它与该问题的其他答案几乎相同,只是使用global关键字而不是$_GLOBAL数组来访问内核对象。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM