如何从我想要的任何 class 中获取 PHP-DI 容器的实例?

How to get instance of PHP-DI container from any class I want?

我在我的 PHP 项目中使用 PHP-DI 6 容器。在我的程序开始时,我只是初始化容器并获得 Application class 并注入所有依赖项。

    $container   = new Container();
    $application = $container->get(Application::class);

    $application->initialize();
    $application->run();

在下图中,您可以看到我在项目中使用的 classes。

Asterisk Dispatcher 被注入应用程序 class。

private $asteriskDispatcher;

public function __construct(AsteriskDispatcher $asteriskDispatcher)
{
    $this->asteriskDispatcher = $asteriskDispatcher;
}

然后,在 AsteriskDispatcher class 中,我需要创建一个 Asterisk Manager 实例列表,它在不久的将来也会包含一些依赖项。

我不想通过所有 class 继承容器。有没有一种方法可以将 PHP-DI 容器初始化为单例,这样我就可以随时使用它来创建一些对象?

我现在就是这样做的,我只是在 AsteriskDispatcher class 中创建了一个 PHP-DI 容器的新实例,这看起来太糟糕了。

class AsteriskDispatcher implements AsteriskDispatcherInterface
{
    private $listOfAsteriskManagers;

    public function __construct()
    {
        $configurations = AsteriskConnectionsConfiguration::$connectionsConfiguration;

        $this->listOfAsteriskManagers = new \SplDoublyLinkedList();

        $container = new Container();

        foreach ($configurations as $configuration)
        {
            $this->listOfAsteriskManagers->push($container->make(AsteriskManager::class,
                array('configuration' => $configuration)));
        }
    }
}

我真的很想了解如何在不违反 SOLID 原则的情况下使用 PHP-DI 容器。

来自documentation

If you need to use the make() method inside a service, or a controller, or whatever, it is recommended that you type-hint against FactoryInterface *. That avoids coupling your code to the container. DI\FactoryInterface is automatically bound to DI\Container so you can inject it without any configuration.

*强调我的

所以您应该将 AsteriskDispatcher 构造函数更改为:

public function __construct(FactoryInterface $factory) {
  // your code ...
  // more of your code ...

  $factory->make(AsteriskManager::class, ['configuration' => $configuration]);

  // the rest of your code.

}

PS:Singletons are evil(大部分)。