Я использую отражение, чтобы проверить, есть ли у класса определенный родительский класс, а затем возвращаю его экземпляр.
if(class_exists($classname)){
$cmd_class = new \ReflectionClass($classname);
if($cmd_class->isSubClassOf(self::$base_cmd)){
// var_dump($cmd_class);exit;
return $cmd_class->newInstance();
}
}
Я хочу иметь возможность модульного тестирования этих экземпляров объектов, но я не знаю, есть ли способ использовать внедрение зависимостей в этом случае. Я думал о том, чтобы использовать фабрики для получения зависимостей. Является ли заводская модель лучшим вариантом?
My thought was to use factories to get dependencies
Используя этот метод, вы все равно не будете знать, какие зависимости есть у класса.
Я бы рекомендовал пойти дальше и разрешить зависимости с помощью Reflection API.
На самом деле вы можете набирать аргументы конструктора подсказок, и Reflection API полностью способен читать подсказки типов.
Вот очень простой пример:
<?php
class Email {
public function send()
{
echo "Sending E-Mail";
}
}
class ClassWithDependency {
protected $email;
public function __construct( Email $email )
{
$this->email = $email;
}
public function sendEmail()
{
$this->email->send();
}
}$class = new \ReflectionClass('ClassWithDependency');
// Let's get all the constructor parameters
$reflectionParameters = $class->getConstructor()->getParameters();
$dependencies = [];
foreach( $reflectionParameters AS $param )
{
// We instantiate the dependent class
// and push it to the $dependencies array
$dependencies[] = $param->getClass()->newInstance();
}
// The last step is to construct our base object
// and pass in the dependencies array
$instance = $class->newInstanceArgs($dependencies);
$instance->sendEmail(); //Output: Sending E-Mail
Конечно, вам нужно выполнить проверку ошибок самостоятельно (например, если нет Typehint для аргумента конструктора). Также этот пример не обрабатывает вложенные зависимости. Но вы должны получить основную идею.
Подумав об этом, вы даже можете собрать небольшой DI-контейнер, в котором вы настраиваете, какие экземпляры вводить для определенных подсказок типов.
Других решений пока нет …