/** * @test */ public function getRequiredTypes_returns_the_required_types_of_the_injection_target() { // given $Closure = function (A $X, B $Y) { }; $Target = new InjectionTargetClosure($Closure); // when $requiredTypes = $Target->getRequiredTypes(); // then $this->assertEquals(2, count($requiredTypes)); $this->assertTrue(array_key_exists('X', $requiredTypes)); $this->assertEquals('tueena\\spec\\core\\stubs\\A', $requiredTypes['X']->getName()); $this->assertTrue(array_key_exists('Y', $requiredTypes)); $this->assertEquals('tueena\\spec\\core\\stubs\\B', $requiredTypes['Y']->getName()); }
/** * @param ServiceDefinition $ServiceDefinition * @param ServiceDefinitions $ServiceDefinitions * @param ServiceDefinition $InitialServiceDefinition * @param ServiceDefinition[] $alreadyCheckedRequirements * @param array[] $trace * @param \Closure $Closure */ private static function throwOnCircularReferenceOfRequiresServicesHelper(ServiceDefinition $ServiceDefinition, ServiceDefinitions $ServiceDefinitions, ServiceDefinition $InitialServiceDefinition, array &$alreadyCheckedRequirements, array $trace, \Closure $Closure = null) { if ($Closure === null) { return; } $InjectionTarget = new InjectionTargetClosure($Closure); foreach ($InjectionTarget->getRequiredTypes() as $requiredType) { $ServiceDefinition = $ServiceDefinitions->get($requiredType); if (in_array($ServiceDefinition, $alreadyCheckedRequirements)) { continue; } // The second part of the condition ensures, that no exception is thrown // if an init function of a service requires the service itself. This // is absolutely valid. if ($ServiceDefinition === $InitialServiceDefinition && $trace[0][1] !== 'init') { self::throwCircularReferenceException($InitialServiceDefinition, $trace); } $alreadyCheckedRequirements[] = $ServiceDefinition; self::throwOnCircularReferenceOfRequiredServices($ServiceDefinition, $ServiceDefinitions, $InitialServiceDefinition, $alreadyCheckedRequirements, $trace); } }