[DI] Add way to register service with implicit name using the PHP DSL

This commit is contained in:
Nikita Konstantinov 2017-10-20 23:39:56 +03:00 committed by Nicolas Grekas
parent 8cf8d1619f
commit ee4227683d
6 changed files with 76 additions and 5 deletions

View File

@ -31,6 +31,7 @@ class ContainerConfigurator extends AbstractConfigurator
private $instanceof;
private $path;
private $file;
private $anonymousCount = 0;
public function __construct(ContainerBuilder $container, PhpFileLoader $loader, array &$instanceof, string $path, string $file)
{
@ -70,7 +71,7 @@ class ContainerConfigurator extends AbstractConfigurator
final public function services(): ServicesConfigurator
{
return new ServicesConfigurator($this->container, $this->loader, $this->instanceof);
return new ServicesConfigurator($this->container, $this->loader, $this->instanceof, $this->path, $this->anonymousCount);
}
}

View File

@ -29,13 +29,17 @@ class ServicesConfigurator extends AbstractConfigurator
private $container;
private $loader;
private $instanceof;
private $anonymousHash;
private $anonymousCount;
public function __construct(ContainerBuilder $container, PhpFileLoader $loader, array &$instanceof)
public function __construct(ContainerBuilder $container, PhpFileLoader $loader, array &$instanceof, string $path = null, int &$anonymousCount = 0)
{
$this->defaults = new Definition();
$this->container = $container;
$this->loader = $loader;
$this->instanceof = &$instanceof;
$this->anonymousHash = ContainerBuilder::hash($path ?: mt_rand());
$this->anonymousCount = &$anonymousCount;
$instanceof = array();
}
@ -59,14 +63,28 @@ class ServicesConfigurator extends AbstractConfigurator
/**
* Registers a service.
*
* @param string|null $id The service id, or null to create an anonymous service
* @param string|null $class The class of the service, or null when $id is also the class name
*/
final public function set(string $id, string $class = null): ServiceConfigurator
final public function set(?string $id, string $class = null): ServiceConfigurator
{
$defaults = $this->defaults;
$allowParent = !$defaults->getChanges() && empty($this->instanceof);
$definition = new Definition();
$definition->setPublic($defaults->isPublic());
if (null === $id) {
if (!$class) {
throw new \LogicException('Anonymous services must have a class name.');
}
$id = sprintf('%d_%s', ++$this->anonymousCount, preg_replace('/^.*\\\\/', '', $class).'~'.$this->anonymousHash);
$definition->setPublic(false);
} else {
$definition->setPublic($defaults->isPublic());
}
$definition->setAutowired($defaults->isAutowired());
$definition->setAutoconfigured($defaults->isAutoconfigured());
$definition->setBindings($defaults->getBindings());

View File

@ -0,0 +1,11 @@
<?php
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
final class StdClassDecorator
{
public function __construct(\stdClass $foo)
{
$this->foo = $foo;
}
}

View File

@ -0,0 +1,19 @@
services:
service_container:
class: Symfony\Component\DependencyInjection\ContainerInterface
public: true
synthetic: true
listener_aggregator:
class: Bar\FooClass
public: true
arguments: [!tagged listener]
2_stdClass~%s:
class: stdClass
public: false
tags:
- { name: listener }
decorated:
class: Symfony\Component\DependencyInjection\Tests\Fixtures\StdClassDecorator
public: true
arguments: [!service { class: stdClass, public: false }]

View File

@ -0,0 +1,21 @@
<?php
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
use Bar\FooClass;
use stdClass;
use Symfony\Component\DependencyInjection\Tests\Fixtures\StdClassDecorator;
return function (ContainerConfigurator $c) {
$s = $c->services();
$s->set('decorated', stdClass::class);
$s->set(null, StdClassDecorator::class)
->decorate('decorated', 'decorator42')
->args(array(ref('decorator42')));
$s->set('listener_aggregator', FooClass::class)->public()->args(array(tagged('listener')));
$s->set(null, stdClass::class)->tag('listener');
};

View File

@ -61,7 +61,7 @@ class PhpFileLoaderTest extends TestCase
$container->compile();
$dumper = new YamlDumper($container);
$this->assertStringEqualsFile($fixtures.'/config/'.$file.'.expected.yml', $dumper->dump());
$this->assertStringMatchesFormatFile($fixtures.'/config/'.$file.'.expected.yml', $dumper->dump());
}
public function provideConfig()
@ -72,6 +72,7 @@ class PhpFileLoaderTest extends TestCase
yield array('prototype');
yield array('child');
yield array('php7');
yield array('anonymous');
}
/**