Как добавить зависимость в Laravel, когда уже используются параметры конструктора?

Этот вопрос направлен на Laravel для PHP.

abstract class AbstractClass
{
protected $value1;
protected $value2;
protected $value3;

public function __construct($value1, $value2, $value3)
{
$this->value1 = $value1;
$this->value2 = $value2;
$this->value3 = $value3;
}
}

class ClassToBeInjected
{
public function doSomething() {}
}

class ClassOne extends AbstractClass
{
public function __construct($value1, $value2, $value3)
{
parent::__construct($value1, $value2, $value3);
}
}

class ClassTwo extends AbstractClass
{
public function __construct($value1, $value2, $value3)
{
parent::__construct($value1, $value2, $value3);
}
}

Привет. Посмотрите на пример выше. У меня есть два класса, ClassOne и ClassTwo, которые оба расширяют AbstractClass. Я хочу, чтобы оба эти класса могли использовать doSomething() от ClassToBeInjected

Теперь мой реальный вопрос: как мне внедрить класс, когда я уже использую конструктор? Представьте, что у меня есть сервис, который вызывает ClassOne или ClassTwo, например: new ClassOne(1, 2, 3);

Я не могу просто добавить «ClassToBeInjected» к сигнатурам, потому что это может испортить мое печатание, создав видимость того, что его нужно передать вручную. Сотрудник предложил использовать черту в абстрактном классе, но это немного странно мне. Кто-то из Laravel IRC предложил мне сделать это так:

abstract class AbstractClass
{
protected $value1;
protected $value2;
protected $value3;
protected $injectedClass;

public function __construct($value1, $value2, $value3)
{
$this->value1        = $value1;
$this->value2        = $value2;
$this->value3        = $value3;
$this->injectedClass = app()->make(ClassToBeInjected::class);
}
}

Этот пример работает, и я могу жить с этим. Но я не уверен, что это правильный подход и может ли он вызвать какие-либо проблемы в дальнейшем, делая это таким образом.

1

Решение

Вам нужно поместить введенные параметры перед параметрами вашего конструктора:

class ClassWithInjections {
public function __construct(FirstClassToBeInjected $class1, SecondClassToBeInjected $class2, $parameter1, $parameter2) {

}
}

Затем, чтобы использовать свой класс, вы должны сделать это в контейнере приложения:

$instance = app()->make(ClassWithInjections::class, ['parameter1value', 'parameter2value'])

Эта функция плохо документирована, но есть пример Документация по внедрению зависимостей контроллеров что говорит:

Вы все еще можете напечатать подсказку Illuminate\Http\Request и получить доступ к вашему
Параметр id, определяя ваш метод контроллера следующим образом:

/**
* Update the given user.
*
* @param  Request  $request
* @param  string  $id
* @return Response
*/
public function update(Request $request, $id)
{
//
}

Так как метод контроллера также разрешается Сервисный контейнер, Я предполагал, что то же самое будет работать для любых инъекций. Чтение app()->make() метод вы найдете, что это правда.

1

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

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