Skip to content

Commit

Permalink
rename interface injector, add containerfactory
Browse files Browse the repository at this point in the history
  • Loading branch information
zafex committed Jan 20, 2019
1 parent 978b915 commit 51e9d5c
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 57 deletions.
6 changes: 3 additions & 3 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ composer require viloveul/container
```php
require __DIR__ . '/vendor/autoload.php';

$container = new Viloveul\Container\Container();
$container = Viloveul\Container\ContainerFactory::instance();

class YourClassA
{
Expand All @@ -29,7 +29,7 @@ class YourClassB
}
}

$result = $container->factory(YourClassB::class);
$result = $container->make(YourClassB::class);

var_dump($result);
```
Expand Down Expand Up @@ -62,7 +62,7 @@ class YourClassB

$container->set(EntityInterface::class, YourClassA::class);

$result = $container->factory(YourClassB::class);
$result = $container->make(YourClassB::class);

var_dump($result);

Expand Down
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
"php": "~7.0",
"psr/container": "^1.0"
},
"require-dev": {
"viloveul/support": "v1.*|v1.x-dev"
},
"autoload": {
"psr-4": {
"Viloveul\\Container\\": "src/"
Expand Down
96 changes: 49 additions & 47 deletions src/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use ReflectionMethod;
use Viloveul\Container\ContainerException;
use Viloveul\Container\Contracts\Container as IContainer;
use Viloveul\Container\Contracts\Injector as IContainerInjector;
use Viloveul\Container\Contracts\ContainerAware as IContainerAware;

class Container implements IContainer
{
Expand All @@ -32,12 +32,9 @@ class Container implements IContainer
/**
* @param array $definitions
*/
public function __construct(array $definitions = [])
public function __construct()
{
static::setInstance($this);
foreach ($definitions as $key => $param) {
$this->set($key, $param);
}
}

/**
Expand All @@ -49,38 +46,6 @@ public function __get($id)
return $this->get($id);
}

/**
* @param string $class
* @param array $params
* @return mixed
*/
public function factory(string $class, array $params = [])
{
try {
$reflection = new ReflectionClass($class);
if (!$reflection->isInstantiable()) {
throw new ContainerException("{$class} is not instantiable.");
}

$constructor = $reflection->getConstructor();

if (null === $constructor || $constructor->getNumberOfParameters() === 0) {
$object = $reflection->newInstance();
} else {
$object = $reflection->newInstanceArgs($this->resolve($constructor, $params));
}

if ($object instanceof IContainerInjector) {
$object->setContainer($this);
}

return $object;

} catch (ReflectionException $e) {
throw new ContainerException($e->getMessage());
}
}

/**
* @param $id
*/
Expand All @@ -94,7 +59,7 @@ public function get($id)
$this->definitions[$id]['params']
);
} else {
$this->components[$id] = $this->factory(
$this->components[$id] = $this->make(
$this->definitions[$id]['target'],
$this->definitions[$id]['params']
);
Expand Down Expand Up @@ -146,6 +111,38 @@ public function invoke(callable $function, array $params = [])
}
}

/**
* @param string $class
* @param array $params
* @return mixed
*/
public function make(string $class, array $params = [])
{
try {
$reflection = new ReflectionClass($class);
if (!$reflection->isInstantiable()) {
throw new ContainerException("{$class} is not instantiable.");
}

$constructor = $reflection->getConstructor();

if (null === $constructor || $constructor->getNumberOfParameters() === 0) {
$object = $reflection->newInstance();
} else {
$object = $reflection->newInstanceArgs($this->resolve($constructor, $params));
}

if ($object instanceof IContainerAware) {
$object->setContainer($this);
}

return $object;

} catch (ReflectionException $e) {
throw new ContainerException($e->getMessage());
}
}

/**
* @param $id
* @param $target
Expand Down Expand Up @@ -220,11 +217,6 @@ public function set($id, $argument)
public static function setInstance(IContainer $container)
{
static::$instance = $container;
static::$instance->components[IContainer::class] = $container;
static::$instance->definitions[IContainer::class] = [
'target' => get_class($container),
'params' => [],
];
}

/**
Expand All @@ -236,18 +228,28 @@ protected function resolve(ReflectionFunctionAbstract $function, array $params)
{
$parameters = [];
foreach ($function->getParameters() ?: [] as $parameter) {
$name = $parameter->getName();
if ($class = $parameter->getClass()) {
if (true === $this->has($class->getName())) {
if ($this->has($class->getName()) === true) {
$parameters[] = $this->get($class->getName());
} elseif ($class->isInstantiable() === true) {
$parameters[] = $this->factory($class->getName());
$parameters[] = $this->make($class->getName());
} elseif ($parameter->isOptional() !== true) {
if (array_key_exists($name, $params)) {
$parameters[] = $params[$name];
} elseif ($this->has($name) === true) {
$parameters[] = $this->get($name);
} else {
$parameters[] = null;
}
} else {
$parameters[] = $parameter->isOptional() ? $parameter->getDefaultValue() : null;
$parameters[] = $parameter->getDefaultValue();
}
} else {
$name = $parameter->getName();
if (array_key_exists($name, $params)) {
$parameters[] = $params[$name];
} elseif ($parameter->isOptional() !== true && $this->has($name) === true) {
$parameters[] = $this->get($name);
} elseif ($parameter->isOptional()) {
$parameters[] = $parameter->getDefaultValue();
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

namespace Viloveul\Container;

use Viloveul\Container\Container as ContainerClass;
use Viloveul\Container\ContainerFactory;
use Viloveul\Container\Contracts\Container as IContainer;

trait ContainerInjectorTrait
trait ContainerAwareTrait
{
/**
* @var mixed
Expand All @@ -20,7 +20,7 @@ public function getContainer(): IContainer
if ($this->container instanceof IContainer) {
return $this->container;
} else {
$this->container = ContainerClass::getInstance();
$this->container = ContainerFactory::instance();
return $this->container;
}
}
Expand Down
23 changes: 23 additions & 0 deletions src/ContainerFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Viloveul\Container;

use Viloveul\Container\Container;
use Viloveul\Container\Contracts\Container as IContainer;
use Viloveul\Container\Contracts\ContainerFactory as IContainerFactory;

class ContainerFactory implements IContainerFactory
{
/**
* @param array $definitions
* @return mixed
*/
public static function instance(array $definitions = []): IContainer
{
$container = Container::getInstance();
foreach ($definitions as $key => $value) {
$container->set($key, $value);
}
return $container;
}
}
16 changes: 13 additions & 3 deletions src/Contracts/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,23 @@
interface Container extends ContainerInterface
{
/**
* @param string $class
* @param $id
*/
public function factory(string $class);
public function __get($id);

public static function getInstance(): self;

/**
* @param $callback
* @param array $params
*/
public function invoke(callable $callback);
public function invoke(callable $callback, array $params = []);

/**
* @param string $class
* @param array $params
*/
public function make(string $class, array $params = []);

/**
* @param $id
Expand All @@ -25,6 +32,9 @@ public function invoke(callable $callback);
*/
public function map($id, $target, array $params = []);

/**
* @param $id
*/
public function raw($id);

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use Viloveul\Container\Contracts\Container;

interface Injector
interface ContainerAware
{
public function getContainer(): Container;

Expand Down
13 changes: 13 additions & 0 deletions src/Contracts/ContainerFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Viloveul\Container\Contracts;

use Viloveul\Container\Contracts\Container;

interface ContainerFactory
{
/**
* @param array $definitions
*/
public static function instance(array $definitions = []): Container;
}

0 comments on commit 51e9d5c

Please sign in to comment.