Skip to content

Commit

Permalink
Merge branch 'feature/psr-11'
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitry-suffi committed Oct 13, 2017
2 parents 5403a53 + d58e507 commit dde91d5
Show file tree
Hide file tree
Showing 14 changed files with 228 additions and 95 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.idea

vander
phpunit.phar
tests/test
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Dependency injection container

Dependency injection container — it is an object to instantiate the class and its dependent objects.

This is in accordance with the recommendations of PSR-11.

It supports the following kinds of dependency injection:

* Constructor injection;
Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"support": {},
"minimum-stability": "stable",
"require": {
"php": ">=7.0.0"
"php": ">=7.0.0",
"psr/container": "*"
},
"require-dev": {
"phpunit/phpunit": "5.4.*",
Expand Down
60 changes: 24 additions & 36 deletions di/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

namespace suffi\di;

use Psr\Container\ContainerInterface;

/**
* Class Container
* @package suffi\di
*/
class Container
class Container implements ContainerInterface
{
/**
* @var array
Expand Down Expand Up @@ -116,25 +118,27 @@ public function hasDefinition(string $name)
* Set in container
* @param string $key
* @param $instance
* @throws Exception
* @throws ContainerException
*/
public function set(string $key, $instance)
{
if (!is_object($instance)) {
throw new Exception('Value is not object');
throw new ContainerException('Value is not object');
}

/** is not singleton */
$this->container[$key] = $instance;
}

/**
* Get by key
* @param string $key
* @return object|false
* @inheritdoc
*/
public function get(string $key)
public function get($key)
{
if (!is_string($key)) {
throw new ContainerException("Identifier is not string");
}

if (isset($this->singletones[$key])) {
return $this->singletones[$key];
}
Expand All @@ -148,20 +152,23 @@ public function get(string $key)
return $this->container[$key];
}

if (isset($this->aliases[$key])) {
return $this->get($this->aliases[$key]);
if ($this->hasAlias($key)) {
return $this->get($this->getAlias($key));
}

return false;
throw new NotFoundException("No entry was found for $key identifier");

}

/**
* Has instance by key
* @param string $key
* @return bool
* @inheritdoc
*/
public function has(string $key)
public function has($key)
{
if (!is_string($key)) {
throw new ContainerException("Identifier is not string");
}

return $this->hasSingleton($key) || isset($this->container[$key]) || ($this->hasAlias($key) && $this->has($this->getAlias($key)));
}

Expand All @@ -178,40 +185,21 @@ public function remove(string $key)
* Set singleton in container
* @param string $key
* @param object $instance
* @throws Exception
* @throws ContainerException
*/
public function setSingleton(string $key, $instance)
{
if ($this->hasSingleton($key)) {
throw new Exception($key . ' is singleton!');
throw new ContainerException($key . ' is singleton!');
}

if (!is_object($instance)) {
throw new Exception('Value is not object');
throw new ContainerException('Value is not object');
}

$this->singletones[$key] = $instance;
}

/**
* Get singleton by key
* @param string $key
* @return Object|false
*/
protected function getSingleton(string $key)
{
return $this->singletones[$key] ?? false;
}

/**
* Remove singleton by $key
* @param string $key
*/
protected function removeSingleton(string $key)
{
unset($this->singletones[$key]);
}

/**
* Has singleton by $key
* @param string $key
Expand Down
14 changes: 14 additions & 0 deletions di/ContainerException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace suffi\di;

use Psr\Container\ContainerExceptionInterface;

/**
* Class Exception
* @package suffi\di
*/
class ContainerException extends \Exception implements ContainerExceptionInterface
{

}
29 changes: 15 additions & 14 deletions di/Definition.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ final class Definition
public function __construct(Container $container, string $name, string $className)
{
if (!$name) {
throw new \Exception('Name is not found!');
throw new ContainerException('Name is not found!');
}

if (!$className) {
throw new \Exception('ClassName is not found!');
throw new ContainerException('ClassName is not found!');
}

$this->container = $container;
Expand Down Expand Up @@ -114,12 +114,13 @@ public function setter(string $paramName, $paramValue)

/**
* @return object
* @throws Exception
* @throws NotFoundException
* @throws ContainerException
*/
public function make()
{
if (!class_exists($this->className)) {
throw new Exception(sprintf('Class %s not found', $this->className));
throw new NotFoundException(sprintf('Class %s not found', $this->className));
}

$reflection = new \ReflectionClass($this->className);
Expand Down Expand Up @@ -157,7 +158,7 @@ public function make()
} else {
/** No is optional */
if (!$param->isOptional()) {
throw new Exception(sprintf('Do not set the parameter %s to constructor', $param->getName()));
throw new ContainerException(sprintf('Do not set the parameter %s to constructor', $param->getName()));
}
}
}
Expand All @@ -179,7 +180,7 @@ public function make()

if ($property) {
if (!$property->isPublic()) {
throw new Exception(sprintf('%s Class %s property is not public', $this->className, $name));
throw new ContainerException(sprintf('%s Class %s property is not public', $this->className, $name));
}
if ($property->isStatic()) {
$property->setValue($value);
Expand All @@ -196,15 +197,15 @@ public function make()
$method = $reflection->getMethod($settersName);
if ($method) {
if ($method->isAbstract()) {
throw new Exception(sprintf('%s:%s - abstract class method', $this->className, $settersName));
throw new ContainerException(sprintf('%s:%s - abstract class method', $this->className, $settersName));
}
if (!$method->isPublic()) {
throw new Exception(sprintf('%s:%s is not public method', $this->className, $settersName));
throw new ContainerException(sprintf('%s:%s is not public method', $this->className, $settersName));
}

$parameters = $method->getParameters();
if (!isset($parameters[0])) {
throw new Exception(sprintf('Method %s has no input parameters', $settersName));
throw new ContainerException(sprintf('Method %s has no input parameters', $settersName));
}

$param = $parameters[0];
Expand All @@ -229,16 +230,16 @@ public function make()
/** Init */
if ($this->initMethod) {
if (!method_exists($instance, $this->initMethod)) {
throw new Exception(sprintf('Method %s is not found in class %s', $this->className, $this->initMethod));
throw new ContainerException(sprintf('Method %s is not found in class %s', $this->className, $this->initMethod));
}

$method = $reflection->getMethod($this->initMethod);

if ($method->isAbstract()) {
throw new Exception(sprintf('%s:%s - abstract class method', $this->className, $this->initMethod));
throw new ContainerException(sprintf('%s:%s - abstract class method', $this->className, $this->initMethod));
}
if (!$method->isPublic()) {
throw new Exception(sprintf('%s:%s is not public method', $this->className, $this->initMethod));
throw new ContainerException(sprintf('%s:%s is not public method', $this->className, $this->initMethod));
}

if ($method->isStatic()) {
Expand All @@ -265,7 +266,7 @@ public function init(string $methodName)
* @todo пока только для конструктора и сеттеров, возможно сделать для публичных свойств ?
* @param string $className
* @return object
* @throws Exception
* @throws NotFoundException
*/
protected function resolve(string $className)
{
Expand All @@ -277,7 +278,7 @@ protected function resolve(string $className)
return $this->container->getDefinition($className)->make();
}

throw new Exception(sprintf('Definition for %s is not found', $className));
throw new NotFoundException(sprintf('Definition for %s is not found', $className));
}

/**
Expand Down
12 changes: 0 additions & 12 deletions di/Exception.php

This file was deleted.

29 changes: 14 additions & 15 deletions di/ExtendedContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,27 @@ public function setParentsContainer(Container $parentsContainer)
/**
* @inheritdoc
*/
public function get(string $key)
public function get($key)
{
$obj = parent::get($key);
if (!$obj && !is_null($this->parentsContainer)) {
$obj = $this->parentsContainer->get($key);
try{
$obj = parent::get($key);

return $obj;
}
return $obj;
catch (NotFoundException $e) {
if (!is_null($this->parentsContainer)) {
return $this->parentsContainer->get($key);
} else {
throw $e;
}
}

}

/**
* @inheritdoc
*/
public function has(string $key)
public function has($key)
{
$has = parent::has($key);

Expand Down Expand Up @@ -80,15 +88,6 @@ public function hasDefinition(string $key)
return $has;
}

protected function getSingleton(string $key)
{
$obj = parent::getSingleton($key);
if (!$obj && !is_null($this->parentsContainer)) {
$obj = $this->parentsContainer->getSingleton($key);
}
return $obj;
}

public function hasSingleton(string $key)
{
$has = parent::hasSingleton($key);
Expand Down
14 changes: 14 additions & 0 deletions di/NotFoundException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace suffi\di;

use Psr\Container\NotFoundExceptionInterface;

/**
* Class Exception
* @package suffi\di
*/
class NotFoundException extends ContainerException implements NotFoundExceptionInterface
{

}
2 changes: 2 additions & 0 deletions docs/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Dependency injection container

Dependency injection container — it is an object to instantiate the class and its dependent objects.

This is in accordance with the recommendations of PSR-11.

It supports the following kinds of dependency injection:

* Constructor injection;
Expand Down
Loading

0 comments on commit dde91d5

Please sign in to comment.