This is a question aimed at Laravel for 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);
}
}
Hi. Have a look at the example above. I have two classes, ClassOne and ClassTwo, that both extend AbstractClass. I want both of these classes to be able to use doSomething()
from ClassToBeInjected
Now my real question is, how do I inject the class when I am already using the constructor? Imagine I have a service that calls ClassOne or ClassTwo like so: new ClassOne(1, 2, 3);
I can't just add ´ClassToBeInjected´ to the signatures because that would mess up my typehinting, making it look like it needs to be manually passed in. A coworker suggested to use a trait on the abstract class, but that seems a bit weird to me. Someone on Laravel IRC suggested that I do it like this:
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);
}
}
This example works and I can live with it. But I am not sure if its the correct approach and if it could cause any problems later, doing it this way.
You need to put the injected parameters before your constructor parameters:
class ClassWithInjections {
public function __construct(FirstClassToBeInjected $class1, SecondClassToBeInjected $class2, $parameter1, $parameter2) {
}
}
Then to use your class you must make it within app container:
$instance = app()->make(ClassWithInjections::class, ['parameter1value', 'parameter2value'])
This feature is not well documented, but there's a example on Controllers Dependency Injection Documentation that says:
You may still type-hint the
Illuminate\Http\Request
and access your id parameter by defining your controller method as follows:/** * Update the given user. * * @param Request $request * @param string $id * @return Response */ public function update(Request $request, $id) { // }
So since the controller method is also resolved by the Service Container, I've assumed that the same will work for any injections. Reading the app()->make()
method you'll find that's true.