0

I'm trying to implement a simple DI in a pure OOP application. I wanted to use Dependency injection to manage many services ( Database, RequestValidator, Cache etc. ). I have read many blogs and liked this one from tech-tajawal but I could not really understand where should I include the container that tech-tajawal wrote. Can someone please show me how to do it?

I want it clean and thus want to use constructor based injection. So If I have a class, let's say AbstractBaseController which will inject a dependency called Request, so I will write:

php:

<?php

     namespace src\controllers;
     use system\middlewares\Request as Request;

     abstract class AbstractBaseController {

         private $request;

         public function __construct(Request $request) {
             $this->request = $request;
             return $this;
         }

     }

But this simply throws

Fatal error: Uncaught TypeError: Argument 1 passed to src\controllers\AbstractBaseController::__construct() must be an instance of system\middlewares\Request, none given`

I think the container from tech-tajawal has to be included in my project root someway but I don't know how.

Please excuse my naivety here as I always was framework dependent.

1 Answer 1

1

You should instantiate your container at the very beggining of your application (think of a bootstrap class, or even at the top of index.php itself, considering a very simplistic application), because you will need the container to be ready before all the subsequent instantiations of services.

The only other thing that could probably be executed before the container instantiation are those related to configuration, because those are usually needed for the container to work properly (configuration parameters, PSR-4 autoloading configuration, etc).

For example, suppose that you have a class called MyController that extends the abstract class AbstractBaseController.

Then, on index.php, for example, you could instantiate your container and your controller:

//index.php
$container = new Container();
$controller = $container->get('namespace\of\MyController');
$controller->render();

When you do that, all the dependencies from the constructor would be handled by the autowiring module of your container library.

In a real life application, the instantiation of a controller would be usually handled inside a router, which maps URL addresses, methods and parameters to different classes to be loaded by the container.

One rule of thumb with autowiring, is that you can never call new namespace\of\MyController() directly anymore, because instantiating it manually would require you to pass each of the constructor dependencies (so you are not really using the autowiring feature). The right way to instantiate it is always by using $container->get('namespace\of\MyController').

Sign up to request clarification or add additional context in comments.

5 Comments

In that case, how is constructor injection working? It's like setting a dependency using a setter when I need it ( of course it digs down the dependency tree and resolves others). I simply want it to work how it works for the Laravel framework .
The container is the one responsible for the constructor injection. When you call $container->get(), it is going to do that for you. Laravel does the same thing, its router is configured to call ->get() on the container passing the controller class, so it can resolve the full dependency tree. Am I missing out anything from my answer? I have already accomplished before, what you are trying do do, so I know that it works. If any step of my answer is not clear, please comment here and I'll try to help you.
Hey Thank you, I will try that and let you know :)
Thank you. This has totally worked. But I guess editing your answer with your comments would provide people with specific answer to the question.
For me drawing the analogy to laravel's Route made sense.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.