Skip to content

Instantly share code, notes, and snippets.

@Ocramius
Created July 20, 2012 17:02
Show Gist options
  • Save Ocramius/3151903 to your computer and use it in GitHub Desktop.
Save Ocramius/3151903 to your computer and use it in GitHub Desktop.
DIC container 101 in PHP
<?php
class B {
protected $c;
public function __construct(C $c) {
$this->c = $c;
}
}
class C {}
class MyContainer
{
protected $instances = array();
public function __construct()
{
$this->instances = array(
'B' => function (MyContainer $container) {
return new B($container->get('C'));
},
'C' => function(MyContainer $container) {
return new C();
},
);
}
public function get($name)
{
$cb = $this->instances[$name];
if ($cb instanceof \Closure) {
$this->instances[$name] = $cb($this);
}
return $this->instances[$name];
}
}
$container = new MyContainer();
var_dump($container->get('B'));
@Ocramius
Copy link
Author

@AmyStephen I am not sure what you mean by "exactly the same thing" - looking at https://gist.github.com/AmyStephen/5607606#comment-832169, the code is too stripped down to really follow all the steps.

There some sentences that I believe to be wrong:

Then, the Model requests the Database service in order to inject the database into the Model during construction.

and

That's why I passed the closure with the call back to the single entry point into the Container - so that - in this case - the model can getService('Database') to inject it in when it constructs the class.

Maybe it's just a language problem, but if I understand it correctly, you are trying to achieve lazy-loading by passing closures around your models.

The problem is essentially that the model itself (service? Don't call it "Model" please, "Model" could literally be anything :( ) requests services as far as I understand, and that breaks the DIP by making your object "aware" that it has to pull something.

It also breaks the LSP, since you now cannot inject a mock now, but instead rely on some callback-based signature, trusting the fact that the callback will retrieve a valid object.

In my opinion, you should first focus on writing it correct and forgetting about the lazy-loading problem. The DIC will eventually be able to produce lazy wrappers of your services.

I wrote extensively on this subject in an article that you've probably already read:

http://ocramius.github.io/blog/zf2-and-symfony-service-proxies-with-doctrine-proxies/ (read it later eventually)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment