Skip to content
This repository has been archived by the owner on Jan 21, 2020. It is now read-only.

Commit

Permalink
Merge 8df4fe0 into 9870c5f
Browse files Browse the repository at this point in the history
  • Loading branch information
michalbundyra committed Apr 11, 2018
2 parents 9870c5f + 8df4fe0 commit aec2336
Show file tree
Hide file tree
Showing 13 changed files with 205 additions and 420 deletions.
3 changes: 2 additions & 1 deletion composer.json
Expand Up @@ -23,7 +23,8 @@
},
"require-dev": {
"phpunit/phpunit": "^7.0.2",
"zendframework/zend-coding-standard": "~1.0.0"
"zendframework/zend-coding-standard": "~1.0.0",
"zendframework/zend-container-config-test": "^0.1.0"
},
"conflict": {
"container-interop/container-interop": "<1.2.0"
Expand Down
57 changes: 56 additions & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

113 changes: 87 additions & 26 deletions src/Config.php
@@ -1,7 +1,7 @@
<?php
/**
* @see https://github.com/zendframework/zend-auradi-config for the canonical source repository
* @copyright Copyright (c) 2017 Zend Technologies USA Inc. (https://www.zend.com)
* @copyright Copyright (c) 2017-2018 Zend Technologies USA Inc. (https://www.zend.com)
* @license https://github.com/zendframework/zend-auradi-config/blob/master/LICENSE.md New BSD License
*/

Expand All @@ -12,9 +12,16 @@
use ArrayObject;
use Aura\Di\Container;
use Aura\Di\ContainerConfigInterface;
use Aura\Di\Exception\ServiceNotFound;
use Psr\Container\ContainerInterface;

use function array_search;
use function class_exists;
use function is_array;
use function is_callable;
use function is_string;
use function sprintf;
use function var_export;

/**
* Configuration for the Aura.Di container.
Expand All @@ -34,9 +41,6 @@ class Config implements ContainerConfigInterface
*/
private $config;

/**
* @param array $config
*/
public function __construct(array $config)
{
$this->config = $config;
Expand Down Expand Up @@ -92,10 +96,35 @@ public function define(Container $container)
&& is_array($dependencies['factories'])
) {
foreach ($dependencies['factories'] as $service => $factory) {
if (! $container->has($factory)) {
$container->set($factory, $container->lazyNew($factory));
if (is_callable($factory)) {
$container->set($service, $container->lazy($factory, $container, $service));
continue;
}
$container->set($service, $container->lazyGetCall($factory, '__invoke', $container, $service));

$container->set(
$service,
$container->lazy(function (ContainerInterface $container, string $service) use ($factory) {
if (! is_string($factory) || ! class_exists($factory)) {
throw new ServiceNotFound(sprintf(
'Service %s cannot be initialized by factory %s',
$service,
is_string($factory) ? $factory : var_export($factory, true)
));
}

$instance = new $factory();

if (! is_callable($instance)) {
throw new ServiceNotFound(sprintf(
'Service %s cannot be initalized by non invokable factory %s',
$service,
$factory
));
}

return $instance($container, $service);
}, $container, $service)
);
}
}

Expand All @@ -108,7 +137,16 @@ public function define(Container $container)
$container->set($service, $container->lazyGet($class));
}

$container->set($class, $container->lazyNew($class));
$container->set($class, $container->lazy(function () use ($class) {
if (! is_string($class) || ! class_exists($class)) {
throw new ServiceNotFound(sprintf(
'Service %s cannot be created',
is_string($class) ? $class : var_export($class, true)
));
}

return new $class();
}));
}
}

Expand Down Expand Up @@ -140,35 +178,58 @@ private function marshalDelegators(Container $container, array $dependencies) :
foreach ($dependencies['delegators'] as $service => $delegatorNames) {
$factory = null;

if (isset($dependencies['services'][$service])) {
// Marshal from service
$instance = $dependencies['services'][$service];
$factory = function () use ($instance) {
return $instance;
};
unset($dependencies['services'][$service]);
}

if (isset($dependencies['factories'][$service])) {
// Marshal from factory
$serviceFactory = $dependencies['factories'][$service];
$factory = function () use ($service, $serviceFactory, $container) {
$factory = new $serviceFactory();
if (is_callable($serviceFactory)) {
$factory = $serviceFactory;
} elseif (is_string($serviceFactory) && ! class_exists($serviceFactory)) {
throw new ServiceNotFound(sprintf(
'Service %s cannot by initialized by factory %s; factory class does not exist',
$service,
$serviceFactory
));
} else {
$factory = new $serviceFactory();
}

if (! is_callable($factory)) {
throw new ServiceNotFound(sprintf(
'Service %s cannot by initalized by factory %s; factory is not callable',
$service,
$serviceFactory
));
}

return $factory($container, $service);
};
unset($dependencies['factories'][$service]);
}

if (isset($dependencies['invokables'][$service])) {
// Marshal from invokable
$class = $dependencies['invokables'][$service];
$factory = function () use ($class) {
return new $class();
};
unset($dependencies['invokables'][$service]);
if (isset($dependencies['invokables'])) {
while (false !== ($key = array_search($service, $dependencies['invokables'], true))) {
// Marshal from invokable
$class = $dependencies['invokables'][$key];
$factory = function () use ($class) {
if (! is_string($class) || ! class_exists($class)) {
throw new ServiceNotFound(sprintf(
'Service %s cannot be created',
is_string($class) ? $class : var_export($class, true)
));
}

return new $class();
};
unset($dependencies['invokables'][$key]);

if ($key !== $service) {
$dependencies['aliases'][$key] = $service;
}
}
}

if (! is_callable($factory)) {
if (! $factory) {
continue;
}

Expand Down
46 changes: 32 additions & 14 deletions src/DelegatorFactory.php
@@ -1,7 +1,7 @@
<?php
/**
* @see https://github.com/zendframework/zend-auradi-config for the canonical source repository
* @copyright Copyright (c) 2017 Zend Technologies USA Inc. (https://www.zend.com)
* @copyright Copyright (c) 2017-2018 Zend Technologies USA Inc. (https://www.zend.com)
* @license https://github.com/zendframework/zend-auradi-config/blob/master/LICENSE.md New BSD License
*/

Expand All @@ -10,9 +10,11 @@
namespace Zend\AuraDi\Config;

use Aura\Di\Container;
use Aura\Di\Exception\ServiceNotFound;

use function array_reduce;
use function class_exists;
use function is_callable;
use function sprintf;

/**
* Aura.Di-compatible delegator factory.
Expand Down Expand Up @@ -54,26 +56,42 @@ class DelegatorFactory
public function __construct(array $delegators, callable $factory)
{
$this->delegators = $delegators;
$this->factory = $factory;
$this->factory = $factory;
}

/**
* Build the instance, invoking each delegator with the result of the previous.
*
* @return mixed
* @throws ServiceNotFound
*/
public function build(Container $container, string $serviceName)
{
$factory = $this->factory;
return array_reduce(
$this->delegators,
function ($instance, $delegatorName) use ($serviceName, $container) {
$delegator = is_callable($delegatorName) ? $delegatorName : new $delegatorName();
return $delegator($container, $serviceName, function () use ($instance) {
return $instance;
});
},
$factory()
);
$callback = $this->factory;

foreach ($this->delegators as $delegatorName) {
if (! class_exists($delegatorName)) {
throw new ServiceNotFound(sprintf(
'Delegator class %s does not exist',
$delegatorName
));
}

$delegator = new $delegatorName();

if (! is_callable($delegator)) {
throw new ServiceNotFound(sprintf(
'Delegator class %s is not callable',
$delegatorName
));
}

$instance = $delegator($container, $serviceName, $callback);
$callback = function () use ($instance) {
return $instance;
};
}

return $instance ?? $callback();
}
}

0 comments on commit aec2336

Please sign in to comment.