ResolverDispatcher.php 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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\FactoryDefinition;
  14. use Hyperf\Di\Definition\ObjectDefinition;
  15. use Hyperf\Di\Definition\SelfResolvingDefinitionInterface;
  16. use Hyperf\Di\Exception\InvalidDefinitionException;
  17. use Psr\Container\ContainerInterface;
  18. use RuntimeException;
  19. class ResolverDispatcher implements ResolverInterface
  20. {
  21. protected ?ObjectResolver $objectResolver = null;
  22. protected ?FactoryResolver $factoryResolver = null;
  23. public function __construct(private ContainerInterface $container)
  24. {
  25. }
  26. /**
  27. * Resolve a definition to a value.
  28. *
  29. * @param DefinitionInterface $definition object that defines how the value should be obtained
  30. * @param array $parameters optional parameters to use to build the entry
  31. * @return mixed value obtained from the definition
  32. * @throws InvalidDefinitionException if the definition cannot be resolved
  33. */
  34. public function resolve(DefinitionInterface $definition, array $parameters = [])
  35. {
  36. if ($definition instanceof SelfResolvingDefinitionInterface) {
  37. return $definition->resolve($this->container);
  38. }
  39. $guard = DepthGuard::getInstance();
  40. return $guard->call(
  41. $definition->getName(),
  42. fn () => $this->getDefinitionResolver($definition)->resolve($definition, $parameters)
  43. );
  44. }
  45. /**
  46. * Check if a definition can be resolved.
  47. *
  48. * @param DefinitionInterface $definition object that defines how the value should be obtained
  49. * @param array $parameters optional parameters to use to build the entry
  50. */
  51. public function isResolvable(DefinitionInterface $definition, array $parameters = []): bool
  52. {
  53. if ($definition instanceof SelfResolvingDefinitionInterface) {
  54. return $definition->isResolvable($this->container);
  55. }
  56. $guard = DepthGuard::getInstance();
  57. return $guard->call(
  58. $definition->getName(),
  59. fn () => $this->getDefinitionResolver($definition)->isResolvable($definition, $parameters)
  60. );
  61. }
  62. /**
  63. * Returns a resolver capable of handling the given definition.
  64. *
  65. * @throws RuntimeException no definition resolver was found for this type of definition
  66. */
  67. private function getDefinitionResolver(DefinitionInterface $definition): ResolverInterface
  68. {
  69. return match (true) {
  70. $definition instanceof ObjectDefinition => $this->objectResolver ??= new ObjectResolver($this->container, $this),
  71. $definition instanceof FactoryDefinition => $this->factoryResolver ??= new FactoryResolver($this->container, $this),
  72. default => throw new RuntimeException('No definition resolver was configured for definition of type ' . get_class($definition)),
  73. };
  74. }
  75. }