8000 feature #26768 [DI] Allow autoconfigured calls in PHP (Gary PEGEOT, G… · symfony/symfony@306c599 · GitHub
[go: up one dir, main page]

Skip to content

Commit 306c599

Browse files
committed
feature #26768 [DI] Allow autoconfigured calls in PHP (Gary PEGEOT, GaryPEGEOT)
This PR was merged into the 4.1-dev branch. Discussion ---------- [DI] Allow autoconfigured calls in PHP | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? |no | Deprecations? | no | Tests pass? | yes | Fixed tickets | | License | MIT | Doc PR | Allow to auto-configured method calls like: ```php $container->registerForAutoconfiguration(LoggerAwareInterface::class)->addMethodCall('setLogger', array(new Reference(LoggerInterface::class))); ``` Commits ------- 1d811cb Add test for both _intanceof and manual method setting. 71bf3ce CS fix 15c45ee Add more test-cases 2612f81 Allow autoconfigured calls in PHP.
2 parents 1b1bbd4 + 1d811cb commit 306c599

File tree

5 files changed

+62
-8
lines changed

5 files changed

+62
-8
lines changed

src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,6 @@ public function process(ContainerBuilder $container)
3333
if ($definition->getArguments()) {
3434
throw new InvalidArgumentException(sprintf('Autoconfigured instanceof for type "%s" defines arguments but these are not supported and should be removed.', $interface));
3535
}
36-
if ($definition->getMethodCalls()) {
37-
throw new InvalidArgumentException(sprintf('Autoconfigured instanceof for type "%s" defines method calls but these are not supported and should be removed.', $interface));
38-
}
3936
}
4037

4138
foreach ($container->getDefinitions() as $id => $definition) {
@@ -64,6 +61,7 @@ private function processDefinition(ContainerBuilder $container, $id, Definition
6461
$definition->setInstanceofConditionals(array());
6562
$parent = $shared = null;
6663
$instanceofTags = array();
64+
$instanceofCalls = array();
6765

6866
foreach ($conditionals as $interface => $instanceofDefs) {
6967
if ($interface !== $class && (!$container->getReflectionClass($class, false))) {
@@ -81,7 +79,13 @@ private function processDefinition(ContainerBuilder $container, $id, Definition
8179
$parent = 'instanceof.'.$interface.'.'.$key.'.'.$id;
8280
$container->setDefinition($parent, $instanceofDef);
8381
$instanceofTags[] = $instanceofDef->getTags();
82+
83+
foreach ($instanceofDef->getMethodCalls() as $methodCall) {
84+
$instanceofCalls[] = $methodCall;
85+
}
86+
8487
$instanceofDef->setTags(array());
88+
$instanceofDef->setMethodCalls(array());
8589

8690
if (isset($instanceofDef->getChanges()['shared'])) {
8791
$shared = $instanceofDef->isShared();
@@ -98,6 +102,7 @@ private function processDefinition(ContainerBuilder $container, $id, Definition
98102
$definition = serialize($definition);
99103
$definition = substr_replace($definition, '53', 2, 2);
100104
$definition = substr_replace($definition, 'Child', 44, 0);
105+
/** @var ChildDefinition $definition */
101106
$definition = unserialize($definition);
102107
$definition->setParent($parent);
103108

@@ -117,6 +122,8 @@ private function processDefinition(ContainerBuilder $container, $id, Definition
117122
}
118123
}
119124

125+
$definition->setMethodCalls(array_merge($instanceofCalls, $definition->getMethodCalls()));
126+
120127
// reset fields with "merge" behavior
121128
$abstract
122129
->setBindings($bindings)

src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,16 @@ public function getYamlCompileTests()
207207
'child_service',
208208
'child_service_expected',
209209
);
210+
211+
$container = new ContainerBuilder();
212+
$container->registerForAutoconfiguration(IntegrationTestStub::class)
213+
->addMethodCall('setSunshine', array('supernova'));
214+
yield array(
215+
'instanceof_and_calls',
216+
'main_service',
217+
'main_service_expected',
218+
$container,
219+
);
210220
}
211221
}
212222

src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,16 +200,34 @@ public function testBadInterfaceForAutomaticInstanceofIsOk()
200200
}
201201

202202
/**
203-
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
204-
* @expectedExceptionMessage Autoconfigured instanceof for type "PHPUnit\Framework\TestCase" defines method calls but these are not supported and should be removed.
203+
* Test that autoconfigured calls are handled gracefully.
205204
*/
206-
public function testProcessThrowsExceptionForAutoconfiguredCalls()
205+
public function testProcessForAutoconfiguredCalls()
207206
{
208207
$container = new ContainerBuilder();
209-
$container->registerForAutoconfiguration(parent::class)
210-
->addMethodCall('setFoo');
208+
209+
$expected = array(
210+
array('setFoo', array(
211+
'plain_value',
212+
'%some_parameter%',
213+
)),
214+
array('callBar', array()),
215+
array('isBaz', array()),
216+
);
217+
218+
$container->registerForAutoconfiguration(parent::class)->addMethodCall('setFoo', $expected[0][1]);
219+
$container->registerForAutoconfiguration(self::class)->addMethodCall('callBar');
220+
221+
$def = $container->register('foo', self::class)->setAutoconfigured(true)->addMethodCall('isBaz');
222+
$this->assertEquals(
223+
array(array('isBaz', array())),
224+
$def->getMethodCalls(),
225+
'Definition shouldn\'t have only one method call.'
226+
);
211227

212228
(new ResolveInstanceofConditionalsPass())->process($container);
229+
230+
$this->assertEquals($expected, $container->findDefinition('foo')->getMethodCalls());
213231
}
214232

215233
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
services:
2+
# main_service should look like this in the end
3+
main_service_expected:
4+
class: Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub
5+
public: true
6+
autoconfigure: true
7+
calls:
8+
- [setSunshine, [supernova]]
9+
- [setSunshine, [warm]]
10+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
services:
2+
_instanceof:
3+
Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStubParent:
4+
calls:
5+
- [setSunshine, [warm]]
6+
main_service:
7+
class: Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub
8+
autoconfigure: true
9+
public: true

0 commit comments

Comments
 (0)
0