Skip to content

Commit

Permalink
feature #24632 [DependencyInjection] Anonymous services in PHP DSL (u…
Browse files Browse the repository at this point in the history
…nkind)

This PR was merged into the 4.1-dev branch.

Discussion
----------

[DependencyInjection] Anonymous services in PHP DSL

| Q             | A
| ------------- | ---
| Branch?       | 4.1
| Bug fix?      | no
| New feature?  | enhancement for fluent PHP configs
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #24493
| License       | MIT
| Doc PR        | not yet

See #24493:
```php
$s->anonymous(SendEmailForRegisteredUser::class)->tag('listener');
```

Commits
-------

ee42276 [DI] Add way to register service with implicit name using the PHP DSL
  • Loading branch information
fabpot committed Jan 23, 2018
2 parents 3cbd01a + ee42276 commit 332ad0a
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 5 deletions.
Expand Up @@ -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)
{
Expand Down Expand Up @@ -70,7 +71,7 @@ final public function parameters(): ParametersConfigurator

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);
}
}

Expand Down
Expand Up @@ -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();
}

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

/**
* 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());
Expand Down
@@ -0,0 +1,11 @@
<?php

namespace Symfony\Component\DependencyInjection\Tests\Fixtures;

final class StdClassDecorator
{
public function __construct(\stdClass $foo)
{
$this->foo = $foo;
}
}
@@ -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 }]
@@ -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');
};
Expand Up @@ -61,7 +61,7 @@ public function testConfig($file)
$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()
Expand All @@ -72,6 +72,7 @@ public function provideConfig()
yield array('prototype');
yield array('child');
yield array('php7');
yield array('anonymous');
}

/**
Expand Down

0 comments on commit 332ad0a

Please sign in to comment.