Question

So in Silex, I am attempting to get the $app parameter out of my controller actions and just pass in the dependencies that are relevant to the controller/action.

Generally my controllers have these shared dependencies:

  • Template engine
  • Session provider
  • Translation provider
  • URL generator
  • Validation provider

I've got a base Controller class to accept these on the constructor by default. The controllers inheriting from it also end up taking those parameters as well. Additionally they take other parameters, such as an object repository/store (such as a user repository in an authentication or user controller).

I end up registering the controllers in Silex with at least 5 parameters to the constructor when it seems like I don't see a lot of that in other applications. Feels like I'm doing it wrong.

I also realize that I'm complaining about the same thing that the Pimple DI container "fixes," but using it also seems not quite true to the DI philosophy.

My question: Is there a better way to do what I'm doing?

Was it helpful?

Solution

Yes there are alternative solutions.

  • The first one is to "group" your parameters into new classes like ControllerUtil or things of the sort. That's not always easy or possible though, so I'm not a particular fan of that.

Benjamin Eberlei explains this approach in this blog post: Extending Symfony2: Controller Utilities

  • The second is to use alternative to constructor injection, like property or setter injection. This is not as clean as constructor injection, but it is extremely practical.

Given controllers are generally not the kind of components you want to reinject, reuse or unit-test a lot, so this is an acceptable compromise IMO. I've been using that method for about a year and I can't go back.

Here is a related blog post I wrote on that subject: Controllers as services?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top