/** * Returns a service instance for the passed in identifying type name. If the * instance does not exist, it creates one. * * @param Type $IdentifyingType * @param Injector $Injector * @return object * @throws ServiceNotDefined */ public function getService(Type $IdentifyingType, Injector $Injector) { $identifyingTypeName = $IdentifyingType->getName(); if (isset($this->builtServices[$identifyingTypeName])) { return $this->builtServices[$identifyingTypeName]; } $ServiceDefinition = $this->ServiceDefinitions->get($IdentifyingType); if (is_null($ServiceDefinition)) { $callerFilePath = debug_backtrace()[0]['file']; $callerLineNumber = debug_backtrace()[0]['line']; throw new ServiceNotDefined($IdentifyingType->getName(), $callerFilePath, $callerLineNumber); } if ($ServiceDefinition->hasFactoryFunction()) { $InjectionTarget = new InjectionTargetClosure($ServiceDefinition->getFactoryFunction()); $Service = $Injector->resolve($InjectionTarget); $this->ensureValueImplementsIdentifyingType($ServiceDefinition, $Service); } else { $InjectionTarget = new InjectionTargetConstructor($ServiceDefinition->getImplementingType()); $Service = $Injector->resolve($InjectionTarget); } $this->builtServices[$identifyingTypeName] = $Service; if ($ServiceDefinition->hasInitFunction()) { $InjectionTarget = new InjectionTargetClosure($ServiceDefinition->getInitFunction()); $Injector->resolve($InjectionTarget); } return $Service; }
/** * @test */ public function If_a_service_is_not_defined_with_a_factory_function_the_constructor_of_that_service_gets_injected_with_the_required_services() { // given $serviceDefinitions = new ServiceDefinitions(); $serviceDefinitions->add(IdentifyingType::is(Type::fromName('tueena\\spec\\core\\stubs\\D')), ImplementingType::isTheSame())->add(IdentifyingType::is(Type::fromName('tueena\\spec\\core\\stubs\\E')), ImplementingType::isTheSame()); $ServiceFactory = new ServiceFactory($serviceDefinitions); $Target = new Injector($ServiceFactory); $PropertyDOfE = null; $Closure = function (\tueena\spec\core\stubs\E $E) use(&$PropertyDOfE) { $PropertyDOfE = $E->D; }; // when $Target->resolve(new InjectionTargetClosure($Closure)); // then $this->assertInstanceOf('tueena\\spec\\core\\stubs\\D', $PropertyDOfE); }