2121use Psr \Container \ContainerExceptionInterface ;
2222use Psr \Container \ContainerInterface as PsrContainerInterface ;
2323
24+ /**
25+ * Class ServiceProviderContainer
26+ *
27+ * Implements a PSR-11 compliant dependency injection container using a service provider.
28+ *
29+ * This container SHALL resolve services by delegating to the factories and extensions defined in the
30+ * provided ServiceProviderInterface instance. Services are lazily instantiated on first request and
31+ * cached for subsequent retrieval, enforcing singleton-like behavior within the container scope.
32+ *
33+ * The container supports service extension mechanisms by allowing callable extensions to modify or
34+ * enhance services after construction, based on the service identifier or its concrete class name.
35+ *
36+ * If an optional wrapper container is provided, it SHALL be passed to service factories and extensions,
37+ * allowing for delegation or decoration of service resolution. If omitted, the container defaults to itself.
38+ *
39+ * @package FastForward\Container
40+ */
2441final class ServiceProviderContainer implements ContainerInterface
2542{
2643 /**
27- * @var ServiceProviderInterface provides factories and extensions for service construction
44+ * The service provider supplying factories and extensions for service construction.
45+ *
46+ * This property MUST reference a valid ServiceProviderInterface implementation.
47+ *
48+ * @var ServiceProviderInterface
2849 */
2950 private ServiceProviderInterface $ serviceProvider ;
3051
3152 /**
32- * @var ContainerInterface the underlying container used for delegation, if available
53+ * The container instance used for service resolution and extension application.
54+ *
55+ * This property MAY reference another container for delegation, or default to this container instance.
56+ *
57+ * @var PsrContainerInterface
3358 */
3459 private PsrContainerInterface $ wrapperContainer ;
3560
3661 /**
37- * @var array<string, mixed> cached resolved services by their identifiers
62+ * Cache of resolved services keyed by their identifier or class name.
63+ *
64+ * This array SHALL store already constructed services to enforce singleton-like behavior within the container scope.
65+ *
66+ * @var array<string, mixed>
3867 */
3968 private array $ cache ;
4069
70+ /**
71+ * Constructs a new ServiceProviderContainer instance.
72+ *
73+ * This constructor SHALL initialize the container with a service provider and an optional delegating container.
74+ * If no wrapper container is provided, the container SHALL delegate to itself.
75+ *
76+ * @param ServiceProviderInterface $serviceProvider The service provider supplying factories and extensions.
77+ * @param PsrContainerInterface|null $wrapperContainer An optional container for delegation. Defaults to self.
78+ */
4179 public function __construct (
4280 ServiceProviderInterface $ serviceProvider ,
4381 ?PsrContainerInterface $ wrapperContainer = null ,
@@ -49,9 +87,10 @@ public function __construct(
4987 /**
5088 * Determines if the container can return an entry for the given identifier.
5189 *
52- * @param string $id identifier of the entry to look for
90+ * This method MUST return true if the entry exists in the cache or factories, false otherwise.
5391 *
54- * @return bool true if the entry exists, false otherwise
92+ * @param string $id Identifier of the entry to look for.
93+ * @return bool True if the entry exists, false otherwise.
5594 */
5695 public function has (string $ id ): bool
5796 {
@@ -110,20 +149,16 @@ public function get(string $id): mixed
110149 * service instance. If a corresponding extension is found, it MUST be a callable and
111150 * SHALL be invoked with the container and service instance as arguments.
112151 *
113- * This mechanism allows for post-construction decoration or augmentation of the
114- * resolved service. Extensions MAY be used to modify or enhance the behavior or state
115- * of services after they have been created.
116- *
117- * Implementations MUST ensure that only valid callables are executed and SHOULD avoid
118- * side effects beyond service enhancement. If an extension fails or is not callable,
119- * the method SHALL silently ignore it unless explicitly configured otherwise.
152+ * Extensions MAY be used to modify or enhance services after creation. Invalid extensions
153+ * (non-callables) SHALL be ignored silently.
120154 *
121- * @param string $id The identifier of the resolved service.
122- * @param mixed $service The service instance to be extended.
155+ * @param string $id The identifier of the resolved service.
156+ * @param string $class The fully qualified class name of the service.
157+ * @param mixed $service The service instance to apply extensions to.
123158 *
124159 * @return void
125160 *
126- * @throws ContainerException If any extension fails during invocation .
161+ * @throws ContainerException If an extension callable fails during execution .
127162 */
128163 private function applyServiceExtensions (string $ id , string $ class , mixed $ service ): void
129164 {
0 commit comments