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

Commit

Permalink
Merge branch 'hotfix/10-config-consistent-with-spec'
Browse files Browse the repository at this point in the history
Close #10
  • Loading branch information
weierophinney committed Apr 11, 2018
2 parents 9870c5f + c073e15 commit d3ef310
Show file tree
Hide file tree
Showing 14 changed files with 234 additions and 442 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Expand Up @@ -24,7 +24,14 @@ Versions prior to 0.2.0 were released as the package "webimpress/zend-auradi-con

### Fixed

- Nothing.
- [#10](https://github.com/zendframework/zend-auradi-config/pull/10) fixes
support for invokables configuration. Invokables will be instantiated on
first request. If the key name does not match the class name, an alias will be
created mapping the key to the target class as well.

- [#10](https://github.com/zendframework/zend-auradi-config/pull/10) fixes
support for delegators, ensuring they operate for both invokables and
factory-based services, and always on the canonical name.

## 1.0.0 - 2018-03-15

Expand Down
5 changes: 3 additions & 2 deletions composer.json
Expand Up @@ -22,8 +22,9 @@
"aura/di": "^3.4"
},
"require-dev": {
"phpunit/phpunit": "^7.0.2",
"zendframework/zend-coding-standard": "~1.0.0"
"phpunit/phpunit": "^7.1.2",
"zendframework/zend-coding-standard": "~1.0.0",
"zendframework/zend-container-config-test": "^0.2 || ^1.0"
},
"conflict": {
"container-interop/container-interop": "<1.2.0"
Expand Down
97 changes: 76 additions & 21 deletions 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

0 comments on commit d3ef310

Please sign in to comment.