0

I am creating a MVC-ish framework in PHP. I am trying to implement a DI Container to allow the creation of controller objects (among others).

My MVC framework is pretty typical. Each module (or component if you wish) has a controller responsible for executing requests. These module controllers typically extend a base Controller class. All controllers will accept Request and Response objects as arguments.

The confusion occurs because some controllers may need different arguments in order to function. For example: Many controllers will need a Database object; Controllers which send mail may need a Mailer object; while a controller which logs data may need a Log object. The DI Container will contain the recipes for creating all these controllers.

My front controller needs to be able create any of these controller objects, as specified by a request. Furthermore, each controller needs to be able to create any other controller.

How do I get my front controller and module controllers to access the DI Container in a way that doesn't result in a dependency on the DI Container by each controller?

I actually don't mind if the front controller is dependent on the container, I am more concerned about the module controllers.

Thanks,

3

You're going to have to have that dependency on the DI container somewhere. If it's the front controller, fine, but make sure that the front controller is then the single point of origin for all other controllers. All controllers should be created here.

Your DI Container should be clever enough to resolve dependencies to an unlimited depth. Any dependency a controller might have will get resolved by the container and injected into the controller. If any of those objects also have dependencies they should also get resolved by the container.

In my opinion, this is a good approach for several reasons. It gives you a way of removing calls to service locators or factories. In any class that uses the framework, you'll just need to worry about what that class is doing, and you can safely assume that everything it need will be provided. The other benefit is that you can share stuff across components. Your controller and a different component can reuse the same instance of a db repository or something like that. And of course, there's the testability that DI brings.

  • Thanks for the response Pinetree. What about the module controllers though. If I need a module controller to create another controller or any other object, I would have to either: a) pass the DI Container to the controller or b) pass the Front Controller to the Controller. But this does not seem desirable, it's just an indirect dependency on the DI controller. – Ron Feb 9 '14 at 22:35
  • Well your module controllers are still part of the whole routing/controller creation process, so I guess it would be fine to have the DI container there. And this is all still "framework code", which will have to have some dependencies here and there, especially as it grows in size and complexity. I'd just be careful that the "user code" never gets dependent on the DI container, but gets injected with everything it needs. – Ivan Pintar Feb 10 '14 at 15:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.