Skip to content

Commit

Permalink
- Updated project structure to reflect latest standards
Browse files Browse the repository at this point in the history
- Made container PSR-11 compatible
- Separated Setters and Arguments fully
- Args is now Arguments
- Fixed and tested container serialization for caching
- Updated README
- Added Container class to use as your DI container directly
- Dependencies in container are now cached a bit better
- Reverse dependency searching has been removed, it's now reverse by default and always
  • Loading branch information
Torben Köhn committed Feb 13, 2017
1 parent 7a3f947 commit 62e0435
Show file tree
Hide file tree
Showing 16 changed files with 499 additions and 271 deletions.
2 changes: 0 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ git:
depth: 5

php:
- 5.5
- 5.6
- 7.0
- hhvm

Expand Down
8 changes: 8 additions & 0 deletions Di/Container.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Tale\Di;

class Container implements ContainerInterface
{
use ContainerTrait;
}
56 changes: 52 additions & 4 deletions Di/ContainerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,62 @@

namespace Tale\Di;

interface ContainerInterface
use Tale\Di\Dependency\NotFoundException;
use Tale\DiException;

/**
* Interface ContainerInterface
*
* @package Tale\Di
*/
interface ContainerInterface extends \Psr\Container\ContainerInterface, \Serializable
{

//TODO: Loosen getDependencies() and getDependency() to not rely directly on Dependency
/** @return Dependency[] */
public function getDependencies();
public function getDependency($className, $reverse = true);
public function get($className, $reverse = true);

/**
* @param string $className
*
* @return Dependency|null
*/
public function getDependency($className);

/**
* @param string $className
*
* @return bool
*/
public function has($className);

/**
* @param string $className
*
* @return object
*
* @throws DiException
* @throws NotFoundException
*/
public function get($className);

/**
* @param string $className
* @param bool $persistent
* @param object|null $instance
*
* @return $this
*/
public function register($className, $persistent = true, $instance = null);

/**
* @param $instance
*
* @return $this
*/
public function registerInstance($instance);

/**
* @return $this
*/
public function registerSelf();
}
113 changes: 68 additions & 45 deletions Di/ContainerTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Tale\Di;

use Tale\Di\Dependency\NotFoundException;
use Tale\DiException;

/**
Expand All @@ -20,9 +21,12 @@ trait ContainerTrait
private $dependencies = [];

/**
* Returns all dependencies registered on this container.
*
* @return Dependency[]
* @var Dependency[]
*/
private $resolvedDependencies = [];

/**
* {@inheritdoc}
*/
public function getDependencies()
{
Expand All @@ -31,60 +35,64 @@ public function getDependencies()
}

/**
* Finds a dependency based on its class-name.
*
* @param $className
*
* @param bool $reverse
*
* @return null|Dependency
* {@inheritdoc}
*/
public function getDependency($className, $reverse = true)
public function getDependency($className)
{

//Exact matches are found directly
if (isset($this->dependencies[$className]))
return $this->dependencies[$className];

$depClassNames = array_keys($this->dependencies);
if (isset($this->resolvedDependencies[$className]))
return $this->resolvedDependencies[$className];

if ($reverse)
$depClassNames = array_reverse($depClassNames);
$result = null;
if (isset($this->dependencies[$className])) {

foreach ($depClassNames as $depClassName)
if (is_a($depClassName, $className, true))
return $this->dependencies[$depClassName];
//Exact matches are found directly
$result = $this->dependencies[$className];
} else {

return null;
//Traverse the dep list to find our dep
$depClassNames = array_keys($this->dependencies);

foreach ($depClassNames as $depClassName)
if (is_a($depClassName, $className, true))
$result = $this->dependencies[$depClassName];

}

if (!$result)
return null;

$this->resolvedDependencies[$className] = $result;

return $result;
}

/**
* @param $className
*
* @param bool $reverse
*
* @return null|object
* @throws DiException
* {@inheritdoc}
*/
public function get($className, $reverse = true)
public function has($className)
{

if (!($dep = $this->getDependency($className, $reverse)))
throw new DiException(
return $this->getDependency($className) !== null;
}

/**
* {@inheritdoc}
*/
public function get($className)
{

if (($dep = $this->getDependency($className)) === null)
throw new NotFoundException(
"Failed to locate dependency $className. Register it ".
"with \$container->registerDependency($className::class)"
"with \$container->register($className::class)"
);

return $dep->getInstance();
}

/**
* @param $className
* @param bool $persistent
* @param object $instance
*
* @return $this
* @throws DiException
* {@inheritdoc}
*/
public function register($className, $persistent = true, $instance = null)
{
Expand All @@ -104,30 +112,45 @@ public function register($className, $persistent = true, $instance = null)

/** @var ContainerInterface|ContainerTrait $this */
$dep = new Dependency($className, $persistent, $instance);
$this->dependencies[$className] = $dep;
//Prepend rather than append for iteration reasons (Lastly added dependencies should be found first)
$this->dependencies = [$className => $dep] + $this->dependencies;

//TODO: those two are the workhorses, but everything should be prepared for caching. Just need an elegant way...
$dep->analyze()
->wire($this);

return $this;
}

/**
* @param $instance
*
* @return $this
* @throws DiException
* {@inheritdoc}
*/
public function registerInstance($instance)
{

return $this->register(get_class($instance), true, $instance);
}


/**
* {@inheritdoc}
*/
public function registerSelf()
{

return $this->registerInstance($this);
}

public function serialize()
{

return serialize([
$this->dependencies,
$this->resolvedDependencies
]);
}

public function unserialize($data)
{

list($this->dependencies, $this->resolvedDependencies) = unserialize($data);
}
}
Loading

0 comments on commit 62e0435

Please sign in to comment.