внедрение зависимостей — PHP-DI Не может внедрить созданный класс с параметрами конструктора

Я пытаюсь сделать проект с PHP-DI, но у меня есть проблема.

Это след:

след

Вот код:

Контейнерный класс:

$this->containerBuilder->addDefinitions([
'Configuration' => DI\Object('Hetwan\Core\Configuration')->constructor($this->getRootDir().'/app/config/config.yml'),
'Database' => DI\object('Hetwan\Core\Database')
]);

Класс конфигурации:

namespace Hetwan\Core;

use Symfony\Component\Yaml\Yaml;

class Configuration
{
private $attrs;

public function __construct($configFilePath)
{
$this->attrs = Yaml::parse(file_get_contents($configFilePath));
}

public function get($attrPath)
{
$el = $this->attrs;

foreach (explode('.', $attrPath) as $attr)
{
if (!isset($el[$attr]))
throw new ConfigurationException("Unable to get '{$attrPath}'.\n");

$el = $el[$attr];
}

return $el;
}
}

База данных класса:

namespace Hetwan\Core;

use Hetwan\Core\Configuration;

class Database
{
/**
* @Inject
* @var Configuration
*/
private $config;

private $entityManager;

public function create($entitiesPath)
{
$dbParameters = [
'driver' => 'pdo_mysql',
'user' => $config->get('database.user'),
'password' => $config->get('database.password'),
'dbname' => $config->get('database.name')
];

$this->entityManager = EntityManager::create($dbParameters, Setup::createAnnotationMetadataConfiguration([$entitiesPath], false));
}

public function getEntityManager()
{
return $this->entityManager;
}
}

Я могу получить доступ к $container->get('Configuration') без проблем и все работает.

Но при создании класса Database я думаю, что PHP-D пытается воссоздать экземпляр Configuration, и я не знаю почему, потому что экземпляр singleton уже есть.

Спасибо вам за помощь!

0

Решение

Аннотация @var Configuration скорее всего будет интерпретироваться как имя класса, основанное на пространстве имен файла и объявлениях об использовании, а не на имени службы в контейнере.

Без каких-либо других подсказок автоматический DI, вероятно, будет искать сервис, соответствующий этому полному имени класса, т.е. Hetwan\Core\Configuration, Однако ваш сервис зарегистрирован как Configurationтак не совпадает. Таким образом, DI возвращается к попытке автоматически создать экземпляр, используя new \Hetwan\Core\Configuration(); но терпит неудачу, потому что конструктор имеет обязательный параметр.

Я подозреваю, что вам нужно зарегистрировать службу с полным именем, например:

$this->containerBuilder->addDefinitions([
'Hetwan\Core\Configuration' => DI\Object('Hetwan\Core\Configuration')
->constructor($this->getRootDir().'/app/config/config.yml')
]);

Затем, когда он идет искать экземпляр \Hetwan\Core\Configuration он найдет этот сервис вместо того, чтобы пытаться запустить конструктор.

Руководство по PHP-DI показывает, как вы можете упростить это с помощью магическая константа ::class чтобы:

use Hetwan\Core\Configuration;

$this->containerBuilder->addDefinitions([
Configuration::class => DI\Object()
->constructor($this->getRootDir().'/app/config/config.yml')
]);

В качестве альтернативы вы можете указать PHP-DI, какой сервис внедрить, вместо того, чтобы угадывать его в зависимости от типа свойства, согласно документации на аннотации:

/**
* @Inject("Configuration")
*/
private $config;
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]