Hi everyone, Dependency Injection is a very trendy subject and after reading about it I kinda thought about rewriting the framework I'm doing with dependency injection. So I made my own implementation and was wondering what would you think about it? I have followed the article of Martin Fowler ( http://martinfowler.com/articles/injection.html) with this implementation I have the following : - you have both constructor and setter injection - the Dependency class is a service locator - we have at the same time service locator AND dependency injection - you can always manually inject dependency - you can pass arguments to the injected object constructor So: am I missing something? Do you think it's good enough? here is the code : <?php class Dependency { protected $_singletonInstances = array(); protected $_setInstances = array(); protected $_configuration; public static function getInstance() { static $instance = NULL; if (NULL === $instance) { $instance = new static(); } return $instance; } public function setConfiguration(array $configuration) { $this->_configuration = $configuration; } public function getConfiguration() { return $this->_configuration; } public function __isset($serviceName) { return isset($this->_serviceInstances[$serviceName]); } public function __call($serviceName, $args) { // singleton if (isset($this->_configuration[$serviceName]) && $this->_configuration[$serviceName]['singleton']) { if (!isset($this->_singletonInstances[$serviceName])) { $rc = new \ReflectionClass($this->_configuration[$serviceName]['class']); $this->_singletonInstances[$serviceName] = empty($args) ? $rc->newInstance() : $rc->newInstanceArgs($args); } $ret = $this->_singletonInstances[$serviceName]; } else { // normal if (isset($this->_setInstances[$serviceName])) { $ret = $this->_setInstances[$serviceName]; unset($this->_setInstances[$serviceName]); } else { $rc = new \ReflectionClass($this->_configuration[$serviceName]['class']); $ret = $this->_singletonInstances[$serviceName] = empty($args) ? $rc->newInstance() : $rc->newInstanceArgs($args); } } return $ret; } public function __get($serviceName) { return $this->__call($serviceName, array()); } public function __set($serviceName, $instance) { if (!is_object($instance)) throw new Exception('instance must be an object'); $this->_setInstances[$serviceName] = $instance; } } class DependencyInjectorException extends \Exception { } $di=DependencyInjector::getInstance(); $di->setConfiguration(array( 'database.connector'=>array( 'singleton'=>true, 'class'=>'DatabaseConnector' ), 'database'=>array( 'singleton'=>true, 'class'=>'Database' ) )); class DatabaseConnector{} class Database{ protected $_connector; public function __construct(){ $this->setConnector(DependencyInjector::getInstance()->{'database.connector'}); } public function setConnector($connector){ $this->_connector=$connector; } } class Test{ protected $_database; public function __construct(){ $this->setDatabase(DependencyInjector::getInstance()->database); } public function setDatabase($db){ $this->_database=$db; } public function getDatabase(){ return $this->_database; } } $test=new Test(); var_dump($test->getDatabase()); ?>