Как получить экземпляр контейнера PHP-DI из любого класса, который я хочу? - PullRequest
0 голосов
/ 14 января 2019

Я использую контейнер PHP-DI 6 в своем php-проекте. В самом начале своей программы я просто инициализирую контейнер и получаю класс Application со всеми зависимостями.

    $container = new Container();

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

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

Окей, это круто, на изображении ниже вы можете увидеть классы, которые я использую в своем проекте.

class diagram

Asterisk Dispatcher внедряется в класс Application.

    private $asteriskDispatcher;

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

Затем внутри класса AsteriskDispatcher мне нужно создать список, который заполнен экземплярами Asterisk Manager, который также будет содержать некоторые зависимости в ближайшем будущем. Я не хочу наследовать контейнер через все классы, есть ли способ инициализировать контейнер PHP-DI как синглтон, чтобы я мог использовать его в любой момент, когда захочу создать несколько объектов?

Вот как я делаю это прямо сейчас, я просто создаю новый экземпляр контейнера PHP-DI внутри своего класса AsteriskDispatcher, и это выглядит чертовски ужасно.

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)));
        }
    }
}

Я действительно хочу понять, как я могу использовать контейнер PHP-DI, не нарушая принципы SOLID.

1 Ответ

0 голосов
/ 14 января 2019

Из документации :

Если вам нужно использовать метод make () внутри службы, или контроллера, или чего-то еще, рекомендуется указывать подсказку против FactoryInterface *. Это позволяет избежать связывания вашего кода с контейнером. , DI \ FactoryInterface автоматически связывается с DI \ Container, поэтому вы можете вставить его без какой-либо конфигурации.

* упорная мина

Таким образом, вы должны изменить ваш AsteriskDispatcher конструктор так:

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

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

  // the rest of your code.

}

PS: Одиночки являются злом (в основном).

...