Like promised, even if it didn't generated as much reaction as I expected, here is the code :
PHP Code:
<?php
/*\
* Created on 6 janv. 2005 by Jonas Pfenniger <zimba.tm@gmail.com>
\*/
class DiContainer_Default
{
private
$components = array(),
$instances = array(),
$parent_container = null;
function __construct($container = null)
{
if ($container !== null)
{
$this->parent_container = $container;
}
}
/**
* @todo Method doc
*/
function registerComponent($class_name)
{
$args = func_get_args();
array_shift($args);
$this->components[$class_name] = $args;
}
/**
* Use on last resort
*/
function registerInstance($class_name, $object)
{
$this->instances[$class_name] = $object;
}
function getComponentInstance($class_name)
{
// Container has component
if ($this->instances[$class_name])
{
return $this->instances[$class_name];
}
elseif (array_key_exists($class_name, $this->components))
{
// Create instance if not exists
$args =& $this->components[$class_name];
$refl_class = new ReflectionClass($class_name);
try
{
$construct = $refl_class->getMethod('__construct');
$params = $construct->getParameters();
for($i = 0; $i < count($params); $i++)
{
if ($params[$i]->getClass())
{
// Recursion power
$args[$i] = $this->getComponentInstance($args[$i]);
}
}
} catch(Exception $e) { echo "glups:" . $e->getMessage(); }
// Create class
$c = 'return new '.$class_name.'(';
for($i=0; $i<count($args); $i++)
{
$c .= '$args['.$i.']';
if ($i < count($args) - 1) $c .= ',';
}
$c .= ');';
//echo $c;
$this->instances[$class_name] = eval($c);
return $this->instances[$class_name];
}
elseif ($this->parent_container !== null) // ask parent
{
return $this->parent_container->getComponentInstance($class_name);
}
trigger_error("Component $class_name is not registered", E_USER_ERROR);
}
// TODO : function start, LifeCycle
function start()
{
}
// Add class loader
}
?>
Look, here is how you'd use it :
PHP Code:
<?php
/*\
* Created on 7 janv. 2005 by Jonas Pfenniger <zimba.tm@gmail.com>
\*/
class Boy {
function __construct() { }
public function kiss(&$kisser) {
if (is_object($kisser))
echo "I was kissed by " + get_class($kisser);
else
print_r($kisser);
}
}
class Girl {
private $boy = null;
function __construct(Boy $boy) {
$this->boy = $boy;
}
function kissSomeone() {
$this->boy->kiss($this);
}
}
$x = new DiContainer_Default();
$x->registerComponent("Girl", "Boy");
$x->registerComponent("Boy");
$a = $x->getComponentInstance("Girl");
$a->kissSomeone();
?>
DI describes the relation between the different objects.
For more concrete examples, I'm currently implementing the MVC pattern and you'll be able to see how any class of the framework will be substituable.
Let me know what you thinks
Bookmarks