22
33declare (strict_types=1 );
44
5+ /*
6+ * This file is part of the Micro framework package.
7+ *
8+ * (c) Stanislau Komar <kost@micro-php.net>
9+ *
10+ * For the full copyright and license information, please view the LICENSE
11+ * file that was distributed with this source code.
12+ */
13+
514namespace Micro \Component \DependencyInjection ;
615
16+ use Micro \Component \DependencyInjection \Exception \ServiceRegistrationException ;
717use Micro \Component \DependencyInjection \Proxy \ProxyBuilderInterface ;
818use Micro \Component \DependencyInjection \Proxy \ProxyClassNameGeneratorInterface ;
9- use Psr \Container \ContainerInterface ;
19+ use Psr \Container \ContainerInterface as PsrContainerInterface ;
1020
11- final readonly class ContainerCompiled implements ContainerInterface, ContainerRegistryCompiledInterface
21+ /** @psalm-suppress UnusedClass */
22+ final class ContainerCompiled extends Container implements ContainerRegistryCompiledInterface
1223{
24+ private bool $ isCompiled ;
25+
26+ private PsrContainerInterface $ decorated ;
27+
1328 public function __construct (
14- private ContainerInterface $ decorated ,
15- private ProxyClassNameGeneratorInterface $ classNameGenerator ,
16- private ProxyBuilderInterface $ proxyBuilder
17- )
18- {
29+ private readonly ProxyClassNameGeneratorInterface $ classNameGenerator ,
30+ private readonly ProxyBuilderInterface $ proxyBuilder ,
31+ ?PsrContainerInterface $ decorated = null ,
32+ ) {
33+ $ this ->isCompiled = false ;
34+ $ this ->decorated = $ decorated ?? new Container ();
1935 }
2036
21- public function get (string $ id ): mixed
37+ /**
38+ * @template T of object
39+ *
40+ * @param class-string<T> $id
41+ *
42+ * @psalm-suppress MoreSpecificImplementedParamType
43+ *
44+ * @return T
45+ */
46+ #[\Override]
47+ public function get (string $ id ): object
2248 {
2349 $ proxyClass = $ this ->classNameGenerator ->createProxyClassName ($ id );
24- if (!class_exists ($ proxyClass )) {
50+ if (!class_exists ($ proxyClass )) {
51+ /* @psalm-suppress MixedReturnStatement */
2552 return $ this ->decorated ->get ($ id );
2653 }
2754
28- return new $ proxyClass ($ this );
55+ /**
56+ * @var T $instance
57+ *
58+ * @psalm-suppress MixedMethodCall
59+ */
60+ $ instance = new $ proxyClass ($ this );
61+
62+ return $ instance ;
2963 }
3064
65+ #[\Override]
3166 public function has (string $ id ): bool
3267 {
3368 return $ this ->decorated ->has ($ id );
3469 }
3570
71+ #[\Override]
3672 public function register (string $ id , callable $ service , bool $ force = false ): void
3773 {
38- if (interface_exists ($ id )) {
74+ if (!$ this ->decorated instanceof ContainerRegistryInterface) {
75+ throw new ServiceRegistrationException ('Container can not decorate service because container does not implement ' .ContainerRegistryInterface::class);
76+ }
77+
78+ if ($ this ->isCompiled ) {
79+ throw new ServiceRegistrationException ('Can not register service because container already compiled. ' );
80+ }
81+
82+ if (interface_exists ($ id ) || class_exists ($ id )) {
3983 $ this ->proxyBuilder ->add ($ id );
4084 }
4185
86+ /** @psalm-suppress ArgumentTypeCoercion */
4287 $ this ->decorated ->register ($ id , $ service , $ force );
4388 }
4489
90+ /**
91+ * @psalm-suppress InvalidPropertyAssignmentValue
92+ */
93+ #[\Override]
94+ public function decorate (string $ id , callable $ service , int $ priority = 0 ): void
95+ {
96+ if (!$ this ->decorated instanceof ContainerDecoratorInterface) {
97+ throw new ServiceRegistrationException ('Container can not decorate service because container does not implement ' .ContainerDecoratorInterface::class);
98+ }
99+
100+ if ($ this ->isCompiled ) {
101+ throw new ServiceRegistrationException ('Can not register service because container already compiled. ' );
102+ }
103+
104+ if (interface_exists ($ id ) || class_exists ($ id )) {
105+ $ this ->proxyBuilder ->add ($ id );
106+ }
107+
108+ /** @psalm-suppress ArgumentTypeCoercion */
109+ $ this ->decorated ->decorate ($ id , $ service , $ priority );
110+ }
111+
112+ #[\Override]
45113 public function compile (): void
46114 {
47115 $ this ->proxyBuilder ->build ();
116+
117+ $ this ->isCompiled = true ;
48118 }
49- }
119+ }
0 commit comments