Skip to content
This repository was archived by the owner on Feb 6, 2020. It is now read-only.

Commit 4d373b8

Browse files
committed
Merge branch 'feature/config-interface' into develop
Close #30
2 parents a2e6614 + 71cfb1c commit 4d373b8

File tree

4 files changed

+273
-5
lines changed

4 files changed

+273
-5
lines changed

doc/book/migration.md

Lines changed: 100 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ registered.
2525

2626
## Configuration
2727

28+
A number of changes have been made to configuration of service and plugin
29+
managers:
30+
31+
- Minor changes in configuration arrays may impact your usage.
32+
- `ConfigInterface` implementations and consumers will need updating.
33+
34+
### Configuration arrays
35+
2836
Configuration for v2 consisted of the following:
2937

3038
```php
@@ -77,7 +85,89 @@ In v3, the configuration remains the same, with the following additions:
7785
The main change is the addition of integrated lazy service configuration is now
7886
integrated.
7987

80-
### Invokables
88+
### ConfigInterface
89+
90+
The `ServiceManager` is now immutable, meaning that you cannot configure it
91+
after-the-fact. If your `ConfigInterface` implementation called on the various
92+
methods for injecting new services, such as:
93+
94+
- `setService()`
95+
- `setInvokableClass()`
96+
- `setFactory()`
97+
- `addAbstractFactory()`
98+
- `addInitializer()`
99+
- `addDelegator()`
100+
101+
then you will need to alter the logic to instead aggregate a full configuration
102+
specification. This can then be passed to the `ServiceManager` instance's
103+
`withConfig()` method, which does the following:
104+
105+
- Creates a clone of the manager.
106+
- Merges the incoming configuration with the current configuration within the
107+
clone.
108+
- Returns the clone.
109+
110+
As such, your implementation should return the result of
111+
`$serviceManager->withConfig()`.
112+
113+
As an example, consider this `HelperConfig` implementation from zend-i18n
114+
v2:
115+
116+
```php
117+
class HelperConfig implements ConfigInterface
118+
{
119+
protected $invokables = [
120+
'currencyformat' => 'Zend\I18n\View\Helper\CurrencyFormat',
121+
'dateformat' => 'Zend\I18n\View\Helper\DateFormat',
122+
'numberformat' => 'Zend\I18n\View\Helper\NumberFormat',
123+
'plural' => 'Zend\I18n\View\Helper\Plural',
124+
'translate' => 'Zend\I18n\View\Helper\Translate',
125+
'translateplural' => 'Zend\I18n\View\Helper\TranslatePlural',
126+
];
127+
128+
public function configureServiceManager(ServiceManager $serviceManager)
129+
{
130+
foreach ($this->invokables as $name => $service) {
131+
$serviceManager->setInvokableClass($name, $service);
132+
}
133+
}
134+
}
135+
```
136+
137+
In version 3, this will become:
138+
139+
```php
140+
use Interop\Container\ContainerInterface;
141+
142+
class HelperConfig implements ConfigInterface
143+
{
144+
protected $invokables = [
145+
'currencyformat' => 'Zend\I18n\View\Helper\CurrencyFormat',
146+
'dateformat' => 'Zend\I18n\View\Helper\DateFormat',
147+
'numberformat' => 'Zend\I18n\View\Helper\NumberFormat',
148+
'plural' => 'Zend\I18n\View\Helper\Plural',
149+
'translate' => 'Zend\I18n\View\Helper\Translate',
150+
'translateplural' => 'Zend\I18n\View\Helper\TranslatePlural',
151+
];
152+
153+
public function configureServiceManager(ServiceManager $serviceManager)
154+
{
155+
return $serviceManager->withConfig([
156+
'invokables' => $this->invokables,
157+
]);
158+
}
159+
}
160+
```
161+
162+
### Config class
163+
164+
`Zend\ServiceManager\Config` has been updated to follow the changes to the
165+
`ConfigInterface` and `ServiceManager`. This essentially means that it removes
166+
the various getter methods, and that the `configureServiceManager()` method
167+
instead aggregates the relevant configuration from the configuration passed to
168+
the constructor to pass to `ServiceManager::withConfig()`.
169+
170+
## Invokables
81171

82172
*Invokables no longer exist,* at least, not identically to how they existed in
83173
ZF2.
@@ -135,7 +225,7 @@ if needed).
135225
> }
136226
> ```
137227
138-
### Lazy Services
228+
## Lazy Services
139229
140230
In v2, if you wanted to create a lazy service, you needed to take the following
141231
steps:
@@ -679,8 +769,6 @@ We may re-introduce it via a separate component in the future.
679769

680770
The following interfaces, traits, and classes were *removed*:
681771

682-
- `Zend\ServiceManager\Config`
683-
- `Zend\ServiceManager\ConfigInterface`
684772
- `Zend\ServiceManager\MutableCreationOptionsInterface`; this was previously
685773
used by the `AbstractPluginManager`, and is no longer required as we ship a
686774
separate `PluginManagerInterface`, and because the functionality is
@@ -697,8 +785,15 @@ too often abused under v2, and represent the antithesis of the purpose of the
697785
Service Manager component; dependencies should be directly injected, and the
698786
container should never be composed by objects.
699787

700-
The following classes have changes:
788+
The following classes and interfaces have changes:
701789

702790
- `Zend\ServiceManager\Proxy\LazyServiceFactory` is now marked `final`, and
703791
implements `Zend\ServiceManager\Proxy\DelegatorFactoryInterface`. Its
704792
dependencies and capabilities remain the same.
793+
- `Zend\ServiceManager\ConfigInterface` now is expected to *return* a
794+
`ServiceManager` instance. This is because instances cannot be configured
795+
in-situ; implementers will now need to call `withConfig()` and return the
796+
instance returned by that method.
797+
- `Zend\ServiceManager\Config` was updated to follow the changes to
798+
`ConfigInterface` and `ServiceManager`, and now returns a new
799+
`ServiceManager` instance from `configureServiceManager()`.

src/Config.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php
2+
/**
3+
* Zend Framework (http://framework.zend.com/)
4+
*
5+
* @link http://github.com/zendframework/zf2 for the canonical source repository
6+
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7+
* @license http://framework.zend.com/license/new-bsd New BSD License
8+
*/
9+
10+
namespace Zend\ServiceManager;
11+
12+
use Zend\Stdlib\ArrayUtils;
13+
14+
class Config implements ConfigInterface
15+
{
16+
/**
17+
* Allowed configuration keys
18+
*
19+
* @var array
20+
*/
21+
protected $allowedKeys = [
22+
'abstract_factories' => true,
23+
'aliases' => true,
24+
'delegators' => true,
25+
'factories' => true,
26+
'initializers' => true,
27+
'invokables' => true,
28+
'lazy_services' => true,
29+
'services' => true,
30+
'shared' => true,
31+
];
32+
33+
/**
34+
* @var array
35+
*/
36+
protected $config = [
37+
'abstract_factories' => [],
38+
'aliases' => [],
39+
'delegators' => [],
40+
'factories' => [],
41+
'initializers' => [],
42+
'invokables' => [],
43+
'lazy_services' => [],
44+
'services' => [],
45+
'shared' => [],
46+
];
47+
48+
/**
49+
* Constructor
50+
*
51+
* @param array $config
52+
*/
53+
public function __construct(array $config = [])
54+
{
55+
// Only merge keys we're interested in
56+
foreach (array_keys($config) as $key) {
57+
if (! isset($this->allowedKeys[$key])) {
58+
unset($config[$key]);
59+
}
60+
}
61+
62+
$this->config = ArrayUtils::merge($this->config, $config);
63+
}
64+
65+
/**
66+
* Configure service manager
67+
*
68+
* @param ServiceManager $serviceManager
69+
* @return ServiceManager Returns a new instance with the merged configuration.
70+
*/
71+
public function configureServiceManager(ServiceManager $serviceManager)
72+
{
73+
return $serviceManager->withConfig($this->config);
74+
}
75+
}

src/ConfigInterface.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
/**
3+
* Zend Framework (http://framework.zend.com/)
4+
*
5+
* @link http://github.com/zendframework/zf2 for the canonical source repository
6+
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7+
* @license http://framework.zend.com/license/new-bsd New BSD License
8+
*/
9+
10+
namespace Zend\ServiceManager;
11+
12+
interface ConfigInterface
13+
{
14+
/**
15+
* Configure a service manager.
16+
*
17+
* Implementations should pull configuration from somewhere (typically
18+
* local properties) and pass it to a ServiceManager's withConfig() method,
19+
* returning a new instance.
20+
*
21+
* @param ServiceManager $serviceManager
22+
* @return ServiceManager
23+
*/
24+
public function configureServiceManager(ServiceManager $serviceManager);
25+
}

test/ConfigTest.php

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
/**
3+
* Zend Framework (http://framework.zend.com/)
4+
*
5+
* @link http://github.com/zendframework/zf2 for the canonical source repository
6+
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7+
* @license http://framework.zend.com/license/new-bsd New BSD License
8+
*/
9+
10+
namespace ZendTest\ServiceManager;
11+
12+
use PHPUnit_Framework_TestCase as TestCase;
13+
use Zend\ServiceManager\Config;
14+
use Zend\ServiceManager\ServiceManager;
15+
16+
class ConfigTest extends TestCase
17+
{
18+
public function testPassesKnownServiceConfigKeysToServiceManagerWithConfigMethod()
19+
{
20+
$expected = [
21+
'abstract_factories' => [
22+
__CLASS__,
23+
__NAMESPACE__,
24+
],
25+
'aliases' => [
26+
'foo' => __CLASS__,
27+
'bar' => __NAMESPACE__,
28+
],
29+
'delegators' => [
30+
'foo' => [
31+
__CLASS__,
32+
__NAMESPACE__,
33+
]
34+
],
35+
'factories' => [
36+
'foo' => __CLASS__,
37+
'bar' => __NAMESPACE__,
38+
],
39+
'initializers' => [
40+
__CLASS__,
41+
__NAMESPACE__,
42+
],
43+
'invokables' => [
44+
'foo' => __CLASS__,
45+
'bar' => __NAMESPACE__,
46+
],
47+
'lazy_services' => [
48+
'class_map' => [
49+
__CLASS__ => __CLASS__,
50+
__NAMESPACE__ => __NAMESPACE__,
51+
],
52+
],
53+
'services' => [
54+
'foo' => $this,
55+
],
56+
'shared' => [
57+
__CLASS__ => true,
58+
__NAMESPACE__ => false,
59+
],
60+
];
61+
62+
$config = $expected + [
63+
'foo' => 'bar',
64+
'baz' => 'bat',
65+
];
66+
67+
$services = $this->prophesize(ServiceManager::class);
68+
$services->withConfig($expected)->willReturn('CALLED');
69+
70+
$configuration = new Config($config);
71+
$this->assertEquals('CALLED', $configuration->configureServiceManager($services->reveal()));
72+
}
73+
}

0 commit comments

Comments
 (0)