Laravel 5.6 «Разрешение неразрешимой зависимости ...» при внедрении зависимости - PullRequest
0 голосов
/ 02 июня 2018

Я пытаюсь связать класс в контейнер через промежуточное ПО, и, похоже, он не работает, потому что класс, который я связываю, получил 2 параметра в конструкторе, и они не распознаются.

Я получаю следующее сообщение об ошибке: « Разрешение неразрешимой зависимости [Параметр # 0 [$ base_url]] в классе App \ Services \ Factureaza ».

Вот промежуточное ПО:

<?php

namespace App\Http\Middleware;

use App\Services\Factureaza;
use Closure;

class InitializeInvoiceProvider
{
    public function handle($request, Closure $next)
    {
        app()->singleton(Factureaza::class, function () {
            // get settings by calling a custom helper function
            $settings = json_decode(get_setting('invoicing_provider_settings'), true);
            $api_url = isset($settings['url']) ? $settings['url'] : null;
            $api_key = isset($settings['key']) ? $settings['key'] : null;
            return new Factureaza($api_url, $api_key);
        });

        return $next($request);
    }
}

Класс Factureaza выглядит следующим образом:

<?php

namespace App\Services;

use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\RequestException;

class Factureaza
{
    protected $client;
    protected $base_url;
    protected $api_key;

    public function __construct($base_url, $api_key)
    {
        $this->client = new GuzzleClient([
            'base_uri' => $base_url,
            'verify' => false,
            'auth' => [$api_key, 'x'],
        ]);
        $this->base_url = $base_url;
        $this->api_key = $api_key;
    }
}

Я получаю эту ошибку, когда пытаюсь разрешить зависимость в моем контроллере:

<?php

class InvoicesController extends Controller
{
    protected $api;

    public function __construct()
    {
        $this->api = resolve('App\Services\Factureaza');
    }
}

1 Ответ

0 голосов
/ 02 июня 2018

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

Laravel создает экземпляр контроллера, прежде чем он запустит промежуточное ПО маршрута.Это необходимо сделать, чтобы иметь возможность собрать промежуточное программное обеспечение, которое контроллер может определить в своем конструкторе для построения стека промежуточного программного обеспечения.

Обновление:

Некоторые Возможные обходные пути (не тестировались) без рефакторинга:

1) Использование внедрения метода вместо попытки получить экземпляр в конструкторе:

public function show(Factureaza $factureaza, ...)

2) Использование замыканияпромежуточное программное обеспечение, определенное в конструкторе контроллера, чтобы получить экземпляр и назначить его.

public function __construct()
{
    $this->middleware(function ($request, $next) {
        $this->api = resolve(Factureaza::class);
        return $next($request);
    });
}

Надеемся, что промежуточное программное обеспечение, которое устанавливает информацию, необходимую для синглтона, работало до этого промежуточного программного обеспечения контроллера.

3) Установите промежуточное ПО для установки этого API на контроллере для вас ... потребуется добавить метод к контроллерам для получения этой информации.У вас есть доступ к контроллеру для маршрута, так как он уже создан и назначен для маршрута.

$request->route()->getController()->setApi(...);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...