Laravel 5.6 “Unresolvable dependency resolving…” when doing dependency injection

被刻印的时光 ゝ 提交于 2021-02-11 14:34:03

问题


I am trying to bind a class into the container via a middleware and it doesn't seem to work because the class that I am binding recieved 2 parameters in the constructor and they aren't recognised.

I am getting the following error message: "Unresolvable dependency resolving [Parameter #0 [ $base_url ]] in class App\Services\Factureaza".

Here is the middleware:

<?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);
    }
}

The Factureaza class looks like this:

<?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;
    }
}

I am getting this error when I am trying to resolve the dependency in my controller:

<?php

class InvoicesController extends Controller
{
    protected $api;

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

回答1:


Your binding should be in a Service Provider. The middleware you have isn't ran until after that Controller has been instantiated. There is no singleton bound to the container at this point. The bind is too late in the life cycle to be able to be there for a controller that a route is being dispatched to.

Laravel instantiates the Controller before it runs the route middleware. It needs to do this to be able to gather the middleware that a controller can define in its constructor to build the middleware stack.

Update:

Some Possible work arounds (did not test) without refactoring:

1) Use method injection instead of trying to get an instance in the constructor:

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

2) Use a closure middleware defined in the constructor of the controller to get an instance and assign it.

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

Hopefully the middleware that sets the information that the singleton needs has ran before this controller middleware.

3) Have a middleware set this api on the controller for you ... would require adding a method to the controllers to take this information. You have access to the controller for the route as it has already be instantiated and assigned to the Route.

$request->route()->getController()->setApi(...);


来源:https://stackoverflow.com/questions/50660549/laravel-5-6-unresolvable-dependency-resolving-when-doing-dependency-injecti

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!