/** * 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; }
/** * @param IInjectionTarget $InjectionTarget * @param string $parameterName * @param Type $RequiredType */ public function __construct(IInjectionTarget $InjectionTarget, $parameterName, Type $RequiredType) { $this->RequiredType = $RequiredType; $message = $RequiredType->getName() . ' is not defined as a service (means: has not been added to the ServiceDefinitions instance with the add() method). '; $message .= 'Each parameter of an injection target must have a defined service as type hint.'; parent::__construct($InjectionTarget, $parameterName, $message); }
/** * @param Type $IdentifyingType * @return ServiceDefinition */ public function get(Type $IdentifyingType) { $identifyingTypeName = $IdentifyingType->getName(); return isset($this->serviceDefinitions[$identifyingTypeName]) ? $this->serviceDefinitions[$identifyingTypeName] : null; }
/** * @param ServiceDefinition $ServiceDefinition * @param string $functionType * @param Type $RequiredType * @param string $parameterName */ private static function ensureFactoryFunctionDoesNotRequireTheServiceItself(ServiceDefinition $ServiceDefinition, $functionType, Type $RequiredType, $parameterName) { if ($functionType === 'init') { return; } if ($RequiredType == $ServiceDefinition->getIdentifyingType()) { $message = 'The type hint of the parameter $' . $parameterName . ' is ' . $RequiredType->getName() . '. '; $message .= 'A factory function cannot be injected with the service it is about to build.'; throw new InvalidServiceDefinition($ServiceDefinition, $message); } }