ContainerServiceProvider.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. <?php
  2. declare(strict_types=1);
  3. namespace Yansongda\Artful\Service;
  4. use Closure;
  5. use Hyperf\Context\ApplicationContext as HyperfContainer;
  6. use Hyperf\Pimple\ContainerFactory as DefaultContainer;
  7. use Illuminate\Container\Container as LaravelContainer;
  8. use Psr\Container\ContainerInterface;
  9. use Yansongda\Artful\Artful;
  10. use Yansongda\Artful\Contract\ServiceProviderInterface;
  11. use Yansongda\Artful\Exception\ContainerException;
  12. use Yansongda\Artful\Exception\ContainerNotFoundException;
  13. use Yansongda\Artful\Exception\Exception;
  14. /**
  15. * @codeCoverageIgnore
  16. */
  17. class ContainerServiceProvider implements ServiceProviderInterface
  18. {
  19. private array $detectApplication = [
  20. 'laravel' => LaravelContainer::class,
  21. 'hyperf' => HyperfContainer::class,
  22. ];
  23. /**
  24. * @throws ContainerException
  25. */
  26. public function register(mixed $data = null): void
  27. {
  28. if ($data instanceof ContainerInterface || $data instanceof Closure) {
  29. Artful::setContainer($data);
  30. return;
  31. }
  32. if (Artful::hasContainer()) {
  33. return;
  34. }
  35. foreach ($this->detectApplication as $framework => $application) {
  36. $method = $framework.'Application';
  37. if (class_exists($application) && method_exists($this, $method) && $this->{$method}()) {
  38. return;
  39. }
  40. }
  41. $this->defaultApplication();
  42. }
  43. /**
  44. * @throws ContainerException
  45. * @throws ContainerNotFoundException
  46. */
  47. protected function laravelApplication(): bool
  48. {
  49. Artful::setContainer(static fn () => LaravelContainer::getInstance());
  50. Artful::set(\Yansongda\Artful\Contract\ContainerInterface::class, LaravelContainer::getInstance());
  51. if (!Artful::has(ContainerInterface::class)) {
  52. Artful::set(ContainerInterface::class, LaravelContainer::getInstance());
  53. }
  54. return true;
  55. }
  56. /**
  57. * @throws ContainerException
  58. * @throws ContainerNotFoundException
  59. */
  60. protected function hyperfApplication(): bool
  61. {
  62. if (!HyperfContainer::hasContainer()) {
  63. return false;
  64. }
  65. Artful::setContainer(static fn () => HyperfContainer::getContainer());
  66. Artful::set(\Yansongda\Artful\Contract\ContainerInterface::class, HyperfContainer::getContainer());
  67. if (!Artful::has(ContainerInterface::class)) {
  68. Artful::set(ContainerInterface::class, HyperfContainer::getContainer());
  69. }
  70. return true;
  71. }
  72. /**
  73. * @throws ContainerException
  74. * @throws ContainerNotFoundException
  75. */
  76. protected function defaultApplication(): void
  77. {
  78. if (!class_exists(DefaultContainer::class)) {
  79. throw new ContainerNotFoundException('容器未找到: Init failed! Maybe you should install `hyperf/pimple` first', Exception::CONTAINER_NOT_FOUND);
  80. }
  81. $container = (new DefaultContainer())();
  82. Artful::setContainer($container);
  83. Artful::set(\Yansongda\Artful\Contract\ContainerInterface::class, $container);
  84. }
  85. }