Skip to content
This repository was archived by the owner on Jan 21, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ $factory = new ContainerFactory();
$container = $factory(
new Config([
'dependencies' => [
'services' => [],
'invokables' => [],
'factories' => [],
'aliases' => [],
'delegators' => [],
'extensions' => [],
'services' => [],
'invokables' => [],
'factories' => [],
'aliases' => [],
'delegators' => [],
'extensions' => [],
'shared' => [],
'shared_by_default' => true,
],
// ... other configuration
])
Expand All @@ -62,6 +64,11 @@ The `dependencies` sub associative array can contain the following keys:
for more details.
- `extensions`: an associative array that maps service names to lists of
extension factory names, see the [the section below](#extensions).
- `shared`: associative array that map a service name to a boolean, in order to
indicate the service manager if it should cache or not a service created
through the get method, independant of the shared_by_default setting.
- `shared_by_default`: boolean that indicates whether services created through
the `get` method should be cached. This is `true` by default.

> Please note, that the whole configuration is available in the `$container`
> on `config` key:
Expand Down
29 changes: 22 additions & 7 deletions src/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ public function configureContainer(Container $container) : void
) {
$dependencies = $this->config['dependencies'];
}
$dependencies['shared_by_default'] = isset($dependencies['shared_by_default'])
? (bool) $dependencies['shared_by_default']
: true;

$this->injectServices($container, $dependencies);
$this->injectFactories($container, $dependencies);
Expand Down Expand Up @@ -66,15 +69,15 @@ private function injectFactories(Container $container, array $dependencies) : vo
}

foreach ($dependencies['factories'] as $name => $object) {
$container[$name] = function (Container $c) use ($object, $name) {
$this->setService($container, $dependencies, $name, function (Container $c) use ($object, $name) {
if ($c->offsetExists($object)) {
$factory = $c->offsetGet($object);
} else {
$factory = new $object();
$c[$object] = $c->protect($factory);
}
return $factory(new PsrContainer($c), $name);
};
});
}
}

Expand All @@ -88,14 +91,15 @@ private function injectInvokables(Container $container, array $dependencies) : v

foreach ($dependencies['invokables'] as $name => $object) {
if ($name !== $object) {
$container[$name] = function (Container $c) use ($object) {
return $c->offsetGet($object);
};
$this->setService($container, $dependencies, $name, function (Container $c) use ($object) {
return new $object();
});
}

$container[$object] = function (Container $c) use ($object) {
//$container[$object] = function (Container $c) use ($object) {
$this->setService($container, $dependencies, $object, function (Container $c) use ($object) {
return new $object();
};
});
}
}

Expand Down Expand Up @@ -152,4 +156,15 @@ private function injectDelegators(Container $container, array $dependencies) : v
}
}
}

private function setService(Container $container, array $dependencies, string $name, callable $callback)
{
if (($dependencies['shared_by_default'] === true && ! isset($dependencies['shared'][$name]))
|| (isset($dependencies['shared'][$name]) && $dependencies['shared'][$name] === true)
) {
$container[$name] = $callback;
} else {
$container[$name] = $container->factory($callback);
}
}
}
105 changes: 105 additions & 0 deletions test/ContainerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php
/**
* @see https://github.com/zendframework/zend-pimple-config for the canonical source repository
* @copyright Copyright (c) 2018 Zend Technologies USA Inc. (https://www.zend.com)
* @license https://github.com/zendframework/zend-pimple-config/blob/master/LICENSE.md New BSD License
*/

declare(strict_types=1);

namespace ZendTest\Pimple\Config;

use PHPUnit\Framework\TestCase;
use Zend\Pimple\Config\Config;
use Zend\Pimple\Config\ContainerFactory;

class ContainerTest extends TestCase
{
public function config()
{
yield 'factories' => [['factories' => ['service' => TestAsset\Factory::class]]];
yield 'invokables' => [['invokables' => ['service' => TestAsset\Service::class]]];
yield 'aliases-invokables' => [
[
'aliases' => ['service' => TestAsset\Service::class],
'invokables' => [TestAsset\Service::class => TestAsset\Service::class],
],
];
yield 'aliases-factories' => [
[
'aliases' => ['service' => TestAsset\Service::class],
'factories' => [TestAsset\Service::class => TestAsset\Factory::class],
],
];
}

/**
* @dataProvider config
*/
public function testIsSharedByDefault(array $config)
{
$container = $this->createContainer($config);

$service1 = $container->get('service');
$service2 = $container->get('service');

$this->assertSame($service1, $service2);
}

/**
* @dataProvider config
*/
public function testCanDisableSharedByDefault(array $config)
{
$container = $this->createContainer(array_merge($config, [
'shared_by_default' => false,
]));

$service1 = $container->get('service');
$service2 = $container->get('service');

$this->assertNotSame($service1, $service2);
}

/**
* @dataProvider config
*/
public function testCanDisableSharedForSingleService(array $config)
{
$container = $this->createContainer(array_merge($config, [
'shared' => [
'service' => false,
],
]));

$service1 = $container->get('service');
$service2 = $container->get('service');

$this->assertNotSame($service1, $service2);
}

/**
* @dataProvider config
*/
public function testCanEnableSharedForSingleService(array $config)
{
$container = $this->createContainer(array_merge($config, [
'shared_by_default' => false,
'shared' => [
'service' => true,
],
]));

$service1 = $container->get('service');
$service2 = $container->get('service');

$this->assertSame($service1, $service2);
}

private function createContainer(array $config)
{
$factory = new ContainerFactory();

return $factory(new Config(['dependencies' => $config]));
}
}