Этот вопрос направлен на 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);
}
}
Этот пример работает, и я могу жить с этим. Но я не уверен, что это правильный подход и может ли он вызвать какие-либо проблемы в дальнейшем, делая это таким образом.
Вам нужно поместить введенные параметры перед параметрами вашего конструктора:
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()
метод вы найдете, что это правда.
Других решений пока нет …