Question

I have build a in-house MVC PHP framework and now I am struggling on implementing DI Container. I've adopted the Pimple as a DiC, I have read the book by Chris Hartjes "The Grumpy Programmer's Guide To Building Testable PHP Applications" (which I find a very good and inspiring read, will recommend it highly!), which talks eased me to understand more about TDD. Anyway, If I get a DI in the core of the framework, how should I populate the definitions and ho should I pass it along.

  1. Injecting the container(Injecting in the application object all the way to the user created controller). - WRONG
  2. Forcing the dev-user to 'populate' it in the Bootstrap - WRONG
  3. Singleton - VERY WRONG
  4. Observer Pattern (DiC attached to the observer. Observer as a front end to DiC) - ?(Probably the worst idea :D )

Then how to make the core DiC available in the whole framework (for, lets say, injecting the Configuration Object), without creating any dependencies, unnecessary forcing the user to code it or adding the overhead of creating XML/JSON or any other.

PS: ** I do believe that I will see a lot of answers about the Inversion-of-Control (IoC) and Service Locator. Which I cant seem to get exactly how to implement them.. Reference me to a simple/basic guide.

Was it helpful?

Solution

(disclaimer, I'm the developer of PHP-DI)

I don't really understand your question, it seems to me that if you have full control over the MVC framework, then using DI and a DIC should be pretty easy. Here is a copy of the introduction to DI on PHP-DI homepage:

  • Application needs FooController so:
  • Application gets FooController from the Container, so:
    • Container creates SomeRepository
    • Container creates BarService and gives it SomeRepository
    • Container creates FooController and gives it BarService
  • Application calls FooController
    • FooController calls BarService
      • BarService calls SomeDependency
        • SomeRepository does something

The Container is in charge of creating all the objects (the object graph), and then the non-framework code (controllers, services, …) works without EVER calling the Container.

Then how to make the core DiC available in the whole framework?

Do not make it available in the whole framework.

Each component (object) should have its dependencies injected (for example in the constructor). The container will inject them (because the container creates all the objects), and the container should be called at the root of your application (the front controller).


Example: you want to inject the Configuration object in a controller:

class MyController {
    private $configuration;

    public function __construct(Configuration $configuration) {
        $this->configuration = $configuration;
    }
}

Since that the role of the DIC to create that controller, it will inject the configuration object.

Also, I don't think you should inject the whole configuration object, but just the values you are interested in (but that's another debate).

And also, if you have questions about how to write your controllers, maybe you should read this: Controllers as services?.

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