Dependency Injection into controller constructors

In this documentation Dependency Injection - 4.x

It describes three places injection works:

  • when calling actions
  • invoking console commands

and finally

You can also have dependencies injected into controller constructors.

There is example code for the first two situation but none for the third. And my experiments have turned up no way to do this.

Does anyone know how?

It’s almost exactly the same as with the command example, the only difference being that you have to make sure that you include and pass on the arguments required for the parent class constructor, which in the case of a controller would probably be the server request:

class SomeController extends Controller
{
    public function __construct(\Some\Dependency $dep, \Cake\Http\ServerRequest $request)
    {
        parent::__construct($request);
        
        // ...
    }
    
    // ...
}

Then add the dependencies and the controller to the container, and that should be it:

$container
    ->add(\Some\Dependency::class);

$container
    ->add(\App\Controller\SomeController::class)
    ->addArgument(\Some\Dependency::class)
    ->addArgument(\Cake\Http\ServerRequest::class);
1 Like

Thanks! I didn’t realize the need for this:

IMO its annoying to have to require all this. I love CakePHP, but in other frameworks you can just slap dependencies into constructors and let auto-wiring handle everything else. I would be nice if CakePHP could more close integrate with The Leagues auto-wiring functionality or add a #[CakeService] attribute to classes you want to be injected automatically that wires this up for you.

Does this do what your are wishing for? Auto Wiring

No, because of this: Memory exhaustion when using League ReflectionContainer as a container delegate · Issue #16544 · cakephp/cakephp · GitHub

I had been meaning to sit down and debug that for sometime.

The docs have been updated to show how to avoid the cyclic dependency issue pointed out by @cnizzardini above. We have even changed the signature of Controller::__construct() in 5.x to avoid this cyclic dependency.

1 Like