ObjectResolver.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * This file is part of Hyperf.
  5. *
  6. * @link https://www.hyperf.io
  7. * @document https://hyperf.wiki
  8. * @contact group@hyperf.io
  9. * @license https://github.com/hyperf/hyperf/blob/master/LICENSE
  10. */
  11. namespace Hyperf\Di\Resolver;
  12. use Hyperf\Di\Definition\DefinitionInterface;
  13. use Hyperf\Di\Definition\ObjectDefinition;
  14. use Hyperf\Di\Exception\DependencyException;
  15. use Hyperf\Di\Exception\InvalidDefinitionException;
  16. use Hyperf\Di\ReflectionManager;
  17. use Psr\Container\ContainerInterface;
  18. use Psr\Container\NotFoundExceptionInterface;
  19. class ObjectResolver implements ResolverInterface
  20. {
  21. private ParameterResolver $parameterResolver;
  22. /**
  23. * ObjectResolver constructor.
  24. */
  25. public function __construct(private ContainerInterface $container, private ResolverInterface $definitionResolver)
  26. {
  27. $this->parameterResolver = new ParameterResolver($this->definitionResolver);
  28. }
  29. /**
  30. * Resolve a definition to a value.
  31. *
  32. * @param DefinitionInterface $definition object that defines how the value should be obtained
  33. * @param array $parameters optional parameters to use to build the entry
  34. * @return mixed value obtained from the definition
  35. * @throws InvalidDefinitionException
  36. * @throws DependencyException
  37. */
  38. public function resolve(DefinitionInterface $definition, array $parameters = [])
  39. {
  40. if (! $definition instanceof ObjectDefinition) {
  41. throw InvalidDefinitionException::create(
  42. $definition,
  43. sprintf('Entry "%s" cannot be resolved: the class is not instanceof ObjectDefinition', $definition->getName())
  44. );
  45. }
  46. return $this->createInstance($definition, $parameters);
  47. }
  48. /**
  49. * Check if a definition can be resolved.
  50. *
  51. * @param ObjectDefinition $definition object that defines how the value should be obtained
  52. * @param array $parameters optional parameters to use to build the entry
  53. */
  54. public function isResolvable(DefinitionInterface $definition, array $parameters = []): bool
  55. {
  56. return $definition->isInstantiable();
  57. }
  58. private function createInstance(ObjectDefinition $definition, array $parameters)
  59. {
  60. // Check that the class is instantiable
  61. if (! $definition->isInstantiable()) {
  62. // Check that the class exists
  63. if (! $definition->isClassExists()) {
  64. throw InvalidDefinitionException::create($definition, sprintf('Entry "%s" cannot be resolved: the class doesn\'t exist', $definition->getName()));
  65. }
  66. throw InvalidDefinitionException::create($definition, sprintf('Entry "%s" cannot be resolved: the class is not instantiable', $definition->getName()));
  67. }
  68. $classReflection = null;
  69. try {
  70. $className = $definition->getClassName();
  71. $classReflection = ReflectionManager::reflectClass($className);
  72. $constructorInjection = $definition->getConstructorInjection();
  73. $args = $this->parameterResolver->resolveParameters($constructorInjection, $classReflection->getConstructor(), $parameters);
  74. $object = new $className(...$args);
  75. } catch (NotFoundExceptionInterface $e) {
  76. throw new DependencyException(sprintf('Error while injecting dependencies into %s: %s', $classReflection ? $classReflection->getName() : '', $e->getMessage()), 0, $e);
  77. } catch (InvalidDefinitionException $e) {
  78. throw InvalidDefinitionException::create($definition, sprintf('Entry "%s" cannot be resolved: %s', $definition->getName(), $e->getMessage()));
  79. }
  80. return $object;
  81. }
  82. }