Skip to content

Commit 5764cfe

Browse files
authored
Fix: Decorators with the same priority (#6)
* Fix: Decorators with the same priority - Fixed the issue when only one decorator was applied when several decorators had the same priority; Signed-off-by: Oleksii Bulba <oleksii_bulba@epam.com> * Fix: Decorators with the same priority - Added unset service decorators when the service is initialized; Signed-off-by: Oleksii Bulba <oleksii_bulba@epam.com> * Fix: Decorators with the same priority - Fix unit tests; Signed-off-by: Oleksii Bulba <oleksii_bulba@epam.com> Signed-off-by: Oleksii Bulba <oleksii_bulba@epam.com>
1 parent 580f2c6 commit 5764cfe

File tree

3 files changed

+46
-15
lines changed

3 files changed

+46
-15
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
vendor/
22
composer.lock
33
.phpunit.result.cache
4+
test-coverage-report/

src/Container.php

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,7 @@ public function register(string $id, \Closure $service): void
6060
*/
6161
public function decorate(string $id, \Closure $service, int $priority = 0): void
6262
{
63-
if(!array_key_exists($id, $this->decorators)) {
64-
$this->decorators[$id] = [];
65-
}
66-
67-
$this->decorators[$id][$priority] = $service;
63+
$this->decorators[$id][$priority][] = $service;
6864
}
6965

7066
/**
@@ -100,12 +96,15 @@ protected function initializeService(string $serviceId): void
10096
return;
10197
}
10298

103-
$decorators = $this->decorators[$serviceId];
99+
$decoratorsByPriority = $this->decorators[$serviceId];
100+
krsort($decoratorsByPriority);
104101

105-
ksort($decorators);
106-
107-
foreach ($decorators as $decorator) {
108-
$this->services[$serviceId] = $decorator($this->services[$serviceId], $this);
102+
foreach ($decoratorsByPriority as $decorators) {
103+
foreach ($decorators as $decorator) {
104+
$this->services[$serviceId] = $decorator($this->services[$serviceId], $this);
105+
}
109106
}
107+
108+
unset($this->decorators[$serviceId]);
110109
}
111110
}

tests/unit/ContainerTest.php

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,19 +52,19 @@ public function testDecorateService(): void
5252
$container = new Container();
5353

5454
$container->register('test', function () {
55-
return new NamedService('D');
55+
return new NamedService('A');
5656
});
5757

5858
$container->decorate('test', function (NamedInterface $decorated) {
59-
return new NamedServiceDecorator($decorated, 'C');
59+
return new NamedServiceDecorator($decorated, 'D');
6060
});
6161

6262
$container->decorate('test', function (NamedInterface $decorated) {
63-
return new NamedServiceDecorator($decorated, 'A');
63+
return new NamedServiceDecorator($decorated, 'B');
6464
}, 10);
6565

6666
$container->decorate('test', function (NamedInterface $decorated) {
67-
return new NamedServiceDecorator($decorated, 'B');
67+
return new NamedServiceDecorator($decorated, 'C');
6868
}, 5);
6969

7070
/** @var NamedInterface $result */
@@ -73,6 +73,37 @@ public function testDecorateService(): void
7373
$this->assertInstanceOf(NamedInterface::class, $result);
7474
$this->assertEquals('ABCD', $result->getName());
7575
}
76+
77+
public function testDecoratorsWithSamePriority(): void
78+
{
79+
$container = new Container();
80+
81+
$container->register('test', function () {
82+
return new NamedService('A');
83+
});
84+
85+
$container->decorate('test', function (NamedInterface $decorated) {
86+
return new NamedServiceDecorator($decorated, 'B');
87+
}, 10);
88+
89+
$container->decorate('test', function (NamedInterface $decorated) {
90+
return new NamedServiceDecorator($decorated, 'D');
91+
});
92+
93+
$container->decorate('test', function (NamedInterface $decorated) {
94+
return new NamedServiceDecorator($decorated, 'E');
95+
});
96+
97+
$container->decorate('test', function (NamedInterface $decorated) {
98+
return new NamedServiceDecorator($decorated, 'C');
99+
}, 10);
100+
101+
/** @var NamedInterface $result */
102+
$result = $container->get('test');
103+
$this->assertInstanceOf(NamedServiceDecorator::class, $result);
104+
$this->assertInstanceOf(NamedInterface::class, $result);
105+
$this->assertEquals('ABCDE', $result->getName());
106+
}
76107
}
77108

78109
interface NamedInterface
@@ -102,6 +133,6 @@ public function __construct(
102133

103134
public function getName(): string
104135
{
105-
return $this->name.$this->decorated->getName();
136+
return $this->decorated->getName().$this->name;
106137
}
107138
}

0 commit comments

Comments
 (0)