FactoryResolver.php 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  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\Exception\InvalidDefinitionException;
  15. use Hyperf\Di\Exception\NotCallableException;
  16. use Psr\Container\ContainerInterface;
  17. class FactoryResolver implements ResolverInterface
  18. {
  19. public function __construct(private ContainerInterface $container, private ResolverInterface $resolver)
  20. {
  21. }
  22. /**
  23. * Resolve a factory definition to a value.
  24. *
  25. * @param FactoryDefinition $definition object that defines how the value should be obtained
  26. * @param array $parameters optional parameters to use to build the entry
  27. * @return mixed value obtained from the definition
  28. * @throws InvalidDefinitionException if the definition cannot be resolved
  29. */
  30. public function resolve(DefinitionInterface $definition, array $parameters = [])
  31. {
  32. $callable = null;
  33. try {
  34. $callable = $definition->getFactory();
  35. if (! method_exists($callable, '__invoke')) {
  36. throw new NotCallableException();
  37. }
  38. if (is_string($callable)) {
  39. $callable = $this->container->get($callable);
  40. }
  41. return $callable($this->container, $parameters);
  42. } catch (NotCallableException $e) {
  43. // Custom error message to help debugging
  44. if (is_string($callable) && class_exists($callable) && method_exists($callable, '__invoke')) {
  45. throw new InvalidDefinitionException(sprintf('Entry "%s" cannot be resolved: factory %s. Invokable classes cannot be automatically resolved if autowiring is disabled on the container, you need to enable autowiring or define the entry manually.', $definition->getName(), $e->getMessage()));
  46. }
  47. throw new InvalidDefinitionException(sprintf('Entry "%s" cannot be resolved: factory %s', $definition->getName(), $e->getMessage()));
  48. }
  49. }
  50. /**
  51. * Check if a definition can be resolved.
  52. *
  53. * @param DefinitionInterface $definition object that defines how the value should be obtained
  54. * @param array $parameters optional parameters to use to build the entry
  55. */
  56. public function isResolvable(DefinitionInterface $definition, array $parameters = []): bool
  57. {
  58. return true;
  59. }
  60. }