Доступ к контейнеру где-то

говнокодю некоторый код

сервис

PHP:
  1. class Debugger
  2. {
  3.     private $display;
  4.     private $handler;
  5.  
  6.     public function __construct($display, $handler)
  7.     {
  8.         $this->display = $display;
  9.         $this->handler = $handler;
  10.     }
  11.  
  12.     public function __invoke(Request $request, Response $response)
  13.     {
  14.         set_error_handler(function ($code, $text, $file, $line) {
  15.             throw new ErrorException($text, 0, $code, $file, $line);
  16.         });
  17.  
  18.         set_exception_handler(function (Throwable $throwable) use ($request, $response) {
  19.             call_user_func(
  20.                 new $this->handler, // не будет автовайринга, нужно сделать — container->get($this->handler)
  21.                 $request,
  22.                 $response,
  23.                 [
  24.                     ‘code’ => $throwable->getCode(),
  25.                     ‘text’ => $throwable->getMessage(),
  26.                     ‘file’ => $throwable->getFile(),
  27.                     ‘line’ => $throwable->getLine(),
  28.                 ]
  29.             );
  30.         });
  31.     }
  32. }

провайдер

PHP:
  1. class DebuggerProvider extends Provider
  2. {
  3.     public function register()
  4.     {
  5.         $this->app->container->set(Debugger::class, function () {
  6.             $debugger = $this->app->container->get(‘debugger’);
  7.  
  8.             return new Debugger(
  9.                 $debugger[‘display’],
  10.                 $debugger[‘handler’] // строка ‘DebuggerAction::class’
  11.             );
  12.         });
  13.     }
  14.  
  15.     public function boot(Request $request, Response $response)
  16.     {
  17.         call_user_func(
  18.             $this->app->container->get(Debugger::class),
  19.             $request,
  20.             $response
  21.         );
  22.     }
  23. }

экшен

PHP:
  1. class DebuggerAction extends Action
  2. {
  3.     private $view;
  4.  
  5.     public function __construct(View $view) // не будет работать если экшен не вызван из контейнера
  6.     {
  7.         $this->view = $view; // хотелось бы так
  8.         // $this->view = new View(); // не ну можно и так сделать
  9.     }
  10.  
  11.     public function __invoke(Request $request, Response $response, $args)
  12.     {
  13.         var_dump($args);
  14.  
  15.         $response->statusCode(404); // или $response->statusCode($args[‘code’]);
  16.     }
  17. }

как мне в сервисе стартануть $this->handler из контейнера, чтобы работал автовайринг?

есть мысль такая

PHP:
  1. class DebuggerProvider extends Provider
  2. {
  3.     public function register()
  4.     {
  5.         $this->app->container->set(Debugger::class, function () {
  6.             $debugger = $this->app->container->get(‘debugger’);
  7.  
  8.             return new Debugger(
  9.                 $debugger[‘display’],
  10.                 $this->app->container->get($debugger[‘handler’]) // создали экземпляр, поместив его в контейнер
  11.             );
  12.         });
  13.     }
  14.  
  15.     public function boot(Request $request, Response $response)
  16.     {
  17.         call_user_func(
  18.             $this->app->container->get(Debugger::class),
  19.             $request,
  20.             $response
  21.         );
  22.     }
  23. }
  24.  
  25. class Debugger
  26. {
  27.     private $display;
  28.     private $handler;
  29.  
  30.     public function __construct($display, $handler)
  31.     {
  32.         $this->display = $display;
  33.         $this->handler = $handler; // тут уже экземпляр экшена из контейнера, в нём будет работать автовайринг
  34.     }
  35.  
  36.     public function __invoke(Request $request, Response $response)
  37.     {
  38.         set_error_handler(function ($code, $text, $file, $line) {
  39.             throw new ErrorException($text, 0, $code, $file, $line);
  40.         });
  41.  
  42.         set_exception_handler(function (Throwable $throwable) use ($request, $response) {
  43.             call_user_func(
  44.                 $this->handler, // вызвали экземпляр экшена, new не нужно делать, отработает магия
  45.                 $request,
  46.                 $response,
  47.                 [
  48.                     ‘code’ => $throwable->getCode(),
  49.                     ‘text’ => $throwable->getMessage(),
  50.                     ‘file’ => $throwable->getFile(),
  51.                     ‘line’ => $throwable->getLine(),
  52.                 ]
  53.             );
  54.         });
  55.     }
  56. }
  57.  
  58. class DebuggerAction extends Action
  59. {
  60.     private $view;
  61.  
  62.     public function __construct(View $view) // будет работать — экшен вызван из контейнера
  63.     {
  64.         $this->view = $view;
  65.     }
  66.  
  67.     public function __invoke(Request $request, Response $response, $args)
  68.     {
  69.         var_dump($args);
  70.  
  71.         $response->statusCode(404); // или $response->statusCode($args[‘code’]);
  72.     }
  73. }

Но что мне не нравится, если в провайдере собирать сервис, передавая в конструктор экземпляр экшена — это то, что если ошибки нет в приложухе, то в контейнере постоянно висит как бы лишний экземпляр этого экшена, это нормально?

p.s. если я прокину резольвер (не понимаю сути резольвера, он использует контейнер, так не проще ли использовать везде контейнер, позволив контейнеру автовайрить самого себя) в сервис с параметрами вместе при сборке, то нарушится как бы общая логика сервиса — если его взять отдельно, то тогда нужно чтобы и там был резольвер))) поэтому сервис собирается без передачи в конструктор — резольвера (фактически контейнера)

 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *