8000 [DI] improve psr4-based service discovery with namespace option · symfony/symfony@00d7f6f · GitHub
[go: up one dir, main page]

Skip to content

Commit 00d7f6f

Browse files
committed
[DI] improve psr4-based service discovery with namespace option
1 parent 4173f13 commit 00d7f6f

File tree

9 files changed

+99
-2
lines changed

9 files changed

+99
-2
lines changed

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class YamlFileLoader extends FileLoader
6363

6464
private static $prototypeKeywords = array(
6565
'resource' => 'resource',
66+
'namespace' => 'namespace',
6667
'exclude' => 'exclude',
6768
'parent' => 'parent',
6869
'shared' => 'shared',
@@ -560,12 +561,17 @@ private function parseDefinition($id, $service, $file, array $defaults)
560561
}
561562
}
562563

564+
if (array_key_exists('namespace', $service) && !array_key_exists('resource', $service)) {
565+
throw new InvalidArgumentException(sprintf('A "resource" attribute must be set when the "namespace" attribute is set for service "%s" in %s. Check your YAML syntax.', $id, $file));
566+
}
567+
563568
if (array_key_exists('resource', $service)) {
564569
if (!is_string($service['resource'])) {
565570
throw new InvalidArgumentException(sprintf('A "resource" attribute must be of type string for service "%s" in %s. Check your YAML syntax.', $id, $file));
566571
}
567572
$exclude = isset($service['exclude']) ? $service['exclude'] : null;
568-
$this->registerClasses($definition, $id, $service['resource'], $exclude);
573+
$namespace = isset($service['namespace']) ? $service['namespace'] : $id;
574+
$this->registerClasses($definition, $namespace, $service['resource'], $exclude);
569575
} else {
570576
$this->setDefinition($id, $definition);
571577
}
@@ -804,7 +810,7 @@ private function checkDefinition($id, array $definition, $file)
804810
{
805811
if ($throw = $this->isLoadingInstanceof) {
806812
$keywords = self::$instanceofKeywords;
807-
} elseif ($throw = isset($definition['resource'])) {
813+
} elseif ($throw = (isset($definition['resource']) || isset($definition['namespace']))) {
808814
$keywords = self::$prototypeKeywords;
809815
} else {
810816
$keywords = self::$serviceKeywords;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\OtherDir\Component1\Dir1;
4+
5+
class Service1
6+
{
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\OtherDir\Component1\Dir2;
4+
5+
class Service2
6+
{
7+
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\OtherDir\Component1\Dir3;
4+
5+
class Service3
6+
{
7+
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\OtherDir\Component2\Dir1;
4+
5+
class Service4
6+
{
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\OtherDir\Component2\Dir2;
4+
5+
class Service5
6+
{
7+
8+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
services:
2+
dir1:
3+
namespace: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\OtherDir\
4+
resource: ../Prototype/OtherDir/*/Dir1
5+
tags: [foo]
6+
7+
dir2:
8+
namespace: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\OtherDir\
9+
resource: ../Prototype/OtherDir/*/Dir2
10+
tags: [bar]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
services:
2+
dir1:
3+
namespace: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\OtherDir\
4+
tags: [foo]

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

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,45 @@ public function testPrototype()
390390
$this->assertContains('reflection.Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\Bar', $resources);
391391
}
392392

393+
public function testPrototypeWithNamespace()
394+
{
395+
$container = new ContainerBuilder();
396+
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
397+
$loader->load('services_prototype_namespace.yml');
398+
399+
$ids = array_keys($container->getDefinitions());
400+
sort($ids);
401+
402+
$this->assertSame(array(
403+
Prototype\OtherDir\Component1\Dir1\Service1::class,
404+
Prototype\OtherDir\Component1\Dir2\Service2::class,
405+
Prototype\OtherDir\Component2\Dir1\Service4::class,
406+
Prototype\OtherDir\Component2\Dir2\Service5::class,
407+
'service_container',
408+
), $ids);
409+
410+
$this->assertTrue($container->getDefinition(Prototype\OtherDir\Component1\Dir1\Service1::class)->hasTag('foo'));
411+
$this->assertTrue($container->getDefinition(Prototype\OtherDir\Component2\Dir1\Service4::class)->hasTag('foo'));
412+
$this->assertFalse($container->getDefinition(Prototype\OtherDir\Component1\Dir1\Service1::class)->hasTag('bar'));
413+
$this->assertFalse($container->getDefinition(Prototype\OtherDir\Component2\Dir1\Service4::class)->hasTag('bar'));
414+
415+
$this->assertTrue($container->getDefinition(Prototype\OtherDir\Component1\Dir2\Service2::class)->hasTag('bar'));
416+
$this->assertTrue($container->getDefinition(Prototype\OtherDir\Component2\Dir2\Service5::class)->hasTag('bar'));
417+
$this->assertFalse($container->getDefinition(Prototype\OtherDir\Component1\Dir2\Service2::class)->hasTag('foo'));
418+
$this->assertFalse($container->getDefinition(Prototype\OtherDir\Component2\Dir2\Service5::class)->hasTag('foo'));
419+
}
420+
421+
/**
422+
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
423+
* @expectedExceptionMessageRegExp /A "resource" attribute must be set when the "namespace" attribute is set for service ".+" in .+/
424+
*/
425+
public function testPrototypeWithNamespaceAndNoResource()
426+
{
427+
$container = new ContainerBuilder();
428+
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
429+
$loader->load('services_prototype_namespace_without_resource.yml');
430+
}
431+
393432
public function testDefaults()
394433
{
395434
$container = new ContainerBuilder();

0 commit comments

Comments
 (0)
0