10000 [DI] Add "service_defaults" configuration key · symfony/symfony@93664c8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 93664c8

Browse files
[DI] Add "service_defaults" configuration key
1 parent d0e8476 commit 93664c8

File tree

3 files changed

+79
-14
lines changed

3 files changed

+79
-14
lines changed

src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,20 @@ private function parseDefinitions($content, $file)
146146
if (!is_array($content['services'])) {
147147
throw new InvalidArgumentException(sprintf('The "services" key should contain an array in %s. Check your YAML syntax.', $file));
148148
}
149+
$defaults = isset($content['service_defaults']) ? $content['service_defaults'] : array();
150+
$defaultKeys = array('public', 'tags', 'autowire');
151+
152+
if (!is_array($defaults)) {
153+
throw new InvalidArgumentException(sprintf('Service defaults must be an array, "%s" given in "%s".', gettype($defaults), $file));
154+
}
155+
foreach ($defaults as $key => $default) {
156+
if (!in_array($key, $defaultKeys)) {
157+
throw new InvalidArgumentException(sprintf('The configuration key "%s" cannot be used to define a default value in "%s". Allowed keys are "%s".', $key, $file, implode('", "', $defaultKeys)));
158+
}
159+
}
149160

150161
foreach ($content['services'] as $id => $service) {
151-
$this->parseDefinition($id, $service, $file);
162+
$this->parseDefinition($id, $service, $file, $defaults);
152163
}
153164
}
154165

@@ -158,10 +169,11 @@ private function parseDefinitions($content, $file)
158169
* @param string $id
159170
* @param array $service
160171
* @param string $file
172+
* @param array $defaults
161173
*
162174
* @throws InvalidArgumentException When tags are invalid
163175
*/
164-
private function parseDefinition($id, $service, $file)
176+
private function parseDefinition($id, $service, $file, array $defaults)
165177
{
166178
if (is_string($service) && 0 === strpos($service, '@')) {
167179
$this->container->setAlias($id, substr($service, 1));
@@ -176,7 +188,7 @@ private function parseDefinition($id, $service, $file)
176188
static::checkDefinition($id, $service, $file);
177189

178190
if (isset($service['alias'])) {
179-
$public = !array_key_exists('public', $service) || (bool) $service['public'];
191+
$public = array_key_exists('public', $service) ? (bool) $service['public'] : !empty($defaults['public']);
180192
$this->container->setAlias($id, new Alias($service['alias'], $public));
181193

182194
foreach ($service as $key => $value) {
@@ -190,6 +202,7 @@ private function parseDefinition($id, $service, $file)
190202

191203
if (isset($service['parent'])) {
192204
$definition = new ChildDefinition($service['parent']);
205+
$defaults = array();
193206
} else {
194207
$definition = new Definition();
195208
}
@@ -210,8 +223,9 @@ private function parseDefinition($id, $service, $file)
210223
$definition->setLazy($service['lazy']);
211224
}
212225

213-
if (isset($service['public'])) {
214-
$definition->setPublic($service['public']);
226+
$public = isset($service['public']) ? $service['public'] : (isset($defaults['public']) ? $defaults['public'] : null);
227+
if (null !== $public) {
228+
$definition->setPublic($public);
215229
}
216230

217231
if (isset($service['abstract'])) {
@@ -260,12 +274,13 @@ private function parseDefinition($id, $service, $file)
260274
}
261275
}
262276

263-
if (isset($service['tags'])) {
264-
if (!is_array($service['tags'])) {
277+
$tags = isset($service['tags']) ? $service['tags'] : (isset($defaults['tags']) ? $defaults['tags'] : null);
278+
if (null !== $tags) {
279+
if (!is_array($tags)) {
265280
throw new InvalidArgumentException(sprintf('Parameter "tags" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
266281
}
267282

268-
foreach ($service['tags'] as $tag) {
283+
foreach ($tags as $tag) {
269284
if (!is_array($tag)) {
270285
$tag = array('name' => $tag);
271286
}
@@ -301,11 +316,12 @@ private function parseDefinition($id, $service, $file)
301316
$definition->setDecoratedService($service['decorates'], $renameId, $priority);
302317
}
303318

304-
if (isset($service['autowire'])) {
305-
if (is_array($service['autowire'])) {
306-
$definition->setAutowiredMethods($service['autowire']);
319+
$autowire = isset($service['autowire']) ? $service['autowire'] : (isset($defaults['autowire']) ? $defaults['autowire'] : null);
320+
if (null !== $autowire) {
321+
if (is_array($autowire)) {
322+
$definition->setAutowiredMethods($autowire);
307323
} else {
308-
$definition->setAutowired($service['autowire']);
324+
$definition->setAutowired($autowire);
309325
}
310326
}
311327

@@ -4 F438 26,7 +442,7 @@ private function validate($content, $file)
426442
}
427443

428444
foreach ($content as $namespace => $data) {
429-
if (in_array($namespace, array('imports', 'parameters', 'services'))) {
445+
if (in_array($namespace, array('imports', 'parameters', 'services', 'service_defaults'))) {
430446
continue;
431447
}
432448

@@ -491,7 +507,7 @@ private function resolveServices($value)
491507
private function loadFromExtensions($content)
492508
{
493509
foreach ($content as $namespace => $values) {
494-
if (in_array($namespace, array('imports', 'parameters', 'services'))) {
510+
if (in_array($namespace, array('imports', 'parameters', 'services', 'service_defaults'))) {
495511
continue;
496512
}
497513

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
service_defaults:
2+
public: false
3+
autowire: true
4+
tags:
5+
- name: foo
6+
7+
services:
8+
with_defaults:
9+
class: Foo
10+
11+
with_null:
12+
class: Foo
13+
public: ~
14+
autowire: ~
15+
tags: ~
16+
17+
no_defaults:
18+
class: Foo
19+
public: true
20+
autowire: false
21+
tags: []
22+
23+
no_defaults_child:
24+
parent: no_defaults
25+
autowire: ~
26+
tags:
27+
- name: bar

src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,28 @@ public function testAutowire()
329329
$this->assertEquals(array('set*', 'bar'), $container->getDefinition('autowire_array')->getAutowiredMethods());
330330
}
331331

332+
public function testDefaults()
333+
{
334+
$container = new ContainerBuilder();
335+
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
336+
$loader->load('services28.yml');
337+
338+
$this->assertFalse($container->getDefinition('with_defaults')->isPublic());
339+
$this->assertFalse($container->getDefinition('with_null')->isPublic());
340+
$this->assertTrue($container->getDefinition('no_defaults')->isPublic());
341+
$this->assertTrue($container->getDefinition('no_defaults_child')->isPublic());
342+
343+
$this->assertSame(array('foo' => array(array())), $container->getDefinition('with_defaults')->getTags());
344+
$this->assertSame(array('foo' => array(array())), $container->getDefinition('with_null')->getTags());
345+
$this->assertSame(array(), $container->getDefinition('no_defaults')->getTags());
346+
$this->assertSame(array('bar' => array(array())), $container->getDefinition('no_defaults_child')->getTags());
347+
348+
$this->assertTrue($container->getDefinition('with_defaults')->isAutowired());
349+
$this->assertTrue($container->getDefinition('with_null')->isAutowired());
350+
$this->assertFalse($container->getDefinition('no_defaults')->isAutowired());
351+
$this->assertFalse($container->getDefinition('no_defaults_child')->isAutowired());
352+
}
353+
332354
/**
333355
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
334356
* @expectedExceptionMessage The value of the "decorates" option for the "bar" service must be the id of the service without the "@" prefix (replace "@foo" with "foo").

0 commit comments

Comments
 (0)
0