1

I have built a few MVC web applications now and have been adapting my developments to better suit the best practices, I am now working on another project and have applied all previous knowledge I have gained however I have a few questions on how would the best way to implement dependency injection into my project be.

I have an index.php which looks something along the lines of:

require __DIR__ . '/../vendor/autoload.php';

use Phroute\Phroute\{RouteCollector, Dispatcher};

require __DIR__ . '/../routes.php';

...

Now I did try Pimple however I'm not sure if this is the best option for me or if there are other better options such as aura.

I defined all of the dependencies in the index file such as my database etc, then I wasn't sure on the best method to use these within my controllers. I did think about this method, but it does feel that it would be very unconveniant to repeat myself by throwing the container into every controller's constructor, is this a bad thing to do; if so how can I avoid it so that the container would be kind of "autoloaded" with every controller?

namespace App\Controllers;

#use Pimple\Container;

class Index {

    public function __construct(Pimple\Container $container){

        $this->container = $container;

    }

    public function index(){

        return $this->container['db'];
        // ...

    }

}
wimpydoody
  • 29
  • 2
  • A lot of frameworks solve this by having a base controller. So instead of having duplicate constructors you would have duplicate `extends BaseController` which I guess is a little cleaner? Personally I don't I mind the duplicate constructor approach as it makes the dependencies immediately obvious. – mister martin Oct 17 '16 at 17:38
  • I don't know if I would worry so much in the controller for dependency injection, The controller is a place to stitch all the data together for the view. For sure in Models you should have it, but by doing it in the index you limit the flexibility of the application. – ArtisticPhoenix Oct 17 '16 at 17:39
  • @mistermartin - it would be pointless to have a base class because you would still have to call the constructor with the dependency, so it saves onlny one line of code, which is replaced with `parent::__construct( $dependancy )` so you're actually just adding a line of code in. – ArtisticPhoenix Oct 17 '16 at 17:41
  • I have previously injected my dependencies into a base controller which all my controllers extend however it didn't look too nice so I wasn't sure if there were better and more scaleable methods of doing the same task. – wimpydoody Oct 17 '16 at 17:43
  • Probably the easiest would be to move the code from index into the controller, but it's no longer dependency injection then. It's fine to do it in the constructor if it's something that will always be in a controller. I mean I can see having no constructor in the extended controllers, which would make it cleaner then. – ArtisticPhoenix Oct 17 '16 at 17:46
  • Another problem with having arguments in the controller constructor is the routing library, phroute. I'm not sure if there is a way to pass arguments to the controller as my routes look like this: `$router->get('/', ['App\\Controllers\\Index', 'index']);` – wimpydoody Oct 17 '16 at 17:53
  • @ArtisticPhoenix I think you misunderstood my comment. The base controller gets the dependency injection, any controller that extends it then automatically inherits it. Again, this is exactly how many MVC based frameworks do it. – mister martin Oct 17 '16 at 17:57
  • @mistermartin - no I understand it, I was just trying to say if you need to put other things in the constructor then it dosn't really save any work, because you will always have to pass that parameter though the descendants. For example in CI, they have something kin to `$CI::getInstance()->load('dependancy');` which I know is not dependency injection, but it saves you from having to touch it again. Basically CI is loading it from inside the controller instead of injecting it. – ArtisticPhoenix Oct 17 '16 at 18:01
  • Any idea how I could pass the container to the controllers? I noticed that PHP DI somehow performs this without even touching the constructor, the dependencies are automatically injected and available seen here: http://stackoverflow.com/a/14645306/7032355 – wimpydoody Oct 17 '16 at 18:05
  • The framework I am making will not have any routing such as typical MVC does, instead it uses events to distribute the request to listeners assigned to the route path. Then the lightener callback ( controller method ) gets the Request object injected as the first parameter... But it's a non-traditional MVC frame work. – ArtisticPhoenix Oct 17 '16 at 18:06
  • @wimpydoody - they cant be "injecting it" they are most likly loading it inside a base classes constructor, based on a config files settings. So in the constructor they have ... `Config what should I load?` then they load it using a common loader through a singleton ( in CI at least ). – ArtisticPhoenix Oct 17 '16 at 18:07
  • CI_Conroller.php source file https://github.com/mattbryson/Codeigniter_Code_Complete/blob/master/system/core/CI_Controller.php Line 100 - 107 they load the dependence instead of injecting them. – ArtisticPhoenix Oct 17 '16 at 18:14
  • Hmm, do you have any recommendation for my method? As to how I could inject the container into the constructor of each controller using the phroute routing system? I have had a look at the documentation but could not find how to specify any constructor arguments for the routes. – wimpydoody Oct 17 '16 at 18:20
  • Firstly Pimple is not DIC if you want to have a look on true DIC https://github.com/rdlowrey/Auryn – Linus Oct 18 '16 at 05:01
  • have a look upon this http://stackoverflow.com/questions/16472924/design-patterns-how-to-create-database-object-connection-only-when-needed/16605563#16605563 and any DI container is Serivce locator if injected into Objects – Linus Oct 18 '16 at 05:03
  • @Linus I know that pimple is a simple service locator and not a true container, which was why I asked for other recommended alternatives. I've been looking at aura and auryn, but not sure which is the most suitable. – wimpydoody Oct 18 '16 at 18:03
  • @wimpydoody auryn ofcourse – Linus Oct 18 '16 at 18:11

0 Answers0