Skip to content

Commit ee42276

Browse files
unkindnicolas-grekas
authored andcommitted
[DI] Add way to register service with implicit name using the PHP DSL
1 parent 8cf8d16 commit ee42276

File tree

6 files changed

+76
-5
lines changed

6 files changed

+76
-5
lines changed

src/Symfony/Component/DependencyInjection/Loader/Configurator/ContainerConfigurator.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class ContainerConfigurator extends AbstractConfigurator
3131
private $instanceof;
3232
private $path;
3333
private $file;
34+
private $anonymousCount = 0;
3435

3536
public function __construct(ContainerBuilder $container, PhpFileLoader $loader, array &$instanceof, string $path, string $file)
3637
{
@@ -70,7 +71,7 @@ final public function parameters(): ParametersConfigurator
7071

7172
final public function services(): ServicesConfigurator
7273
{
73-
return new ServicesConfigurator($this->container, $this->loader, $this->instanceof);
74+
return new ServicesConfigurator($this->container, $this->loader, $this->instanceof, $this->path, $this->anonymousCount);
7475
}
7576
}
7677

src/Symfony/Component/DependencyInjection/Loader/Configurator/ServicesConfigurator.php

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,17 @@ class ServicesConfigurator extends AbstractConfigurator
2929
private $container;
3030
private $loader;
3131
private $instanceof;
32+
private $anonymousHash;
33+
private $anonymousCount;
3234

33-
public function __construct(ContainerBuilder $container, PhpFileLoader $loader, array &$instanceof)
35+
public function __construct(ContainerBuilder $container, PhpFileLoader $loader, array &$instanceof, string $path = null, int &$anonymousCount = 0)
3436
{
3537
$this->defaults = new Definition();
3638
$this->container = $container;
3739
$this->loader = $loader;
3840
$this->instanceof = &$instanceof;
41+
$this->anonymousHash = ContainerBuilder::hash($path ?: mt_rand());
42+
$this->anonymousCount = &$anonymousCount;
3943
$instanceof = array();
4044
}
4145

@@ -59,14 +63,28 @@ final public function instanceof(string $fqcn): InstanceofConfigurator
5963

6064
/**
6165
* Registers a service.
66+
*
67+
* @param string|null $id The service id, or null to create an anonymous service
68+
* @param string|null $class The class of the service, or null when $id is also the class name
6269
*/
63-
final public function set(string $id, string $class = null): ServiceConfigurator
70+
final public function set(?string $id, string $class = null): ServiceConfigurator
6471
{
6572
$defaults = $this->defaults;
6673
$allowParent = !$defaults->getChanges() && empty($this->instanceof);
6774

6875
$definition = new Definition();
69-
$definition->setPublic($defaults->isPublic());
76+
77+
if (null === $id) {
78+
if (!$class) {
79+
throw new \LogicException('Anonymous services must have a class name.');
80+
}
81+
82+
$id = sprintf('%d_%s', ++$this->anonymousCount, preg_replace('/^.*\\\\/', '', $class).'~'.$this->anonymousHash);
83+
$definition->setPublic(false);
84+
} else {
85+
$definition->setPublic($defaults->isPublic());
86+
}
87+
7088
$definition->setAutowired($defaults->isAutowired());
7189
$definition->setAutoconfigured($defaults->isAutoconfigured());
7290
$definition->setBindings($defaults->getBindings());
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
4+
5+
final class StdClassDecorator
6+
{
7+
public function __construct(\stdClass $foo)
8+
{
9+
$this->foo = $foo;
10+
}
11+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
services:
3+
service_container:
4+
class: Symfony\Component\DependencyInjection\ContainerInterface
5+
public: true
6+
synthetic: true
7+
listener_aggregator:
8+
class: Bar\FooClass
9+
public: true
10+
arguments: [!tagged listener]
11+
2_stdClass~%s:
12+
class: stdClass
13+
public: false
14+
tags:
15+
- { name: listener }
16+
decorated:
17+
class: Symfony\Component\DependencyInjection\Tests\Fixtures\StdClassDecorator
18+
public: true
19+
arguments: [!service { class: stdClass, public: false }]
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
4+
5+
use Bar\FooClass;
6+
use stdClass;
7+
use Symfony\Component\DependencyInjection\Tests\Fixtures\StdClassDecorator;
8+
9+
return function (ContainerConfigurator $c) {
10+
$s = $c->services();
11+
12+
$s->set('decorated', stdClass::class);
13+
14+
$s->set(null, StdClassDecorator::class)
15+
->decorate('decorated', 'decorator42')
16+
->args(array(ref('decorator42')));
17+
18+
$s->set('listener_aggregator', FooClass::class)->public()->args(array(tagged('listener')));
19+
20+
$s->set(null, stdClass::class)->tag('listener');
21+
};

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public function testConfig($file)
6161
$container->compile();
6262

6363
$dumper = new YamlDumper($container);
64-
$this->assertStringEqualsFile($fixtures.'/config/'.$file.'.expected.yml', $dumper->dump());
64+
$this->assertStringMatchesFormatFile($fixtures.'/config/'.$file.'.expected.yml', $dumper->dump());
6565
}
6666

6767
public function provideConfig()
@@ -72,6 +72,7 @@ public function provideConfig()
7272
yield array('prototype');
7373
yield array('child');
7474
yield array('php7');
75+
yield array('anonymous');
7576
}
7677

7778
/**

0 commit comments

Comments
 (0)