Imagine we have a Request
object and a Controller
object. The Controller
object is constructed with a Request
object, like so:
abstract class Controller {
public $request;
public function __construct(Request $request)
{
$this->request = $request;
}
}
As you can see, this is an abstract class, so in reality a subclass of Controller
will be constructed. Let's imagine the code is something like this:
// Instantiate the request.
$request = new Request($params);
// Instantiate the registration controller.
$controller = new RegistrationController($request);
Now let's say that we add a dependency to our RegistrationController
, like so:
class RegistrationController extends Controller {
private $user_repo;
public function __construct(Request $request, UserRepo $user_repo)
{
parent::__construct($request);
$this->user_repo = $user_repo;
}
}
At this point, what I'd like to do is introduce a dependency injection container to automatically inject the dependencies via the constructor. For this, I've been using PHP-DI. Usually, this would go something like so:
// Instantiate the registration controller.
$controller = $container->get('RegistrationController');
This would then instantiate RegistrationController
with an instance of Request
and an instance of UserRepo
. It'd know to construct with those objects thanks to reflection, but if I wanted I could also override this via a configuration file.
The problem is that the Request
object takes a parameter which is dynamic. I need the Request
object passed to RegistrationController
to be a specific instance, one I've just created.
I essentially want to be able to say: "Give me an instance of this class with all of its dependencies injected, but for a particular parameter, pass in this specific instance".
I've looked to see if PHP-DI (and a hand-full of other DI containers) support this kind of "override" for specific parameters, but so far I can't find anything.
What I want to know is:
- Is there a DI container out there that can do this?
- Is there an alternative approach which would leave the classes clean (I don't want to use annotations or anything else that'll add the container I use as a dependency)?