问题描述
我正在尝试通过中间件将一个类绑定到容器中,但这似乎不起作用,因为我绑定的类在构造函数中收到2个参数,但无法识别它们.
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.
我收到以下错误消息:"解析类App \ Services \ Factureaza 中的[Parameter#0 [$ base_url]]的不可解决的依赖性".
I am getting the following error message: "Unresolvable dependency resolving [Parameter #0 [ $base_url ]] in class 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类如下:
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');
}
}
推荐答案
您的绑定应该在服务提供者中.实例化Controller之后,才会运行您拥有的中间件.此时没有绑定到容器的单例.绑定在生命周期中为时已晚,无法在其中将路由调度到的控制器在那里.
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在运行路由中间件之前实例化Controller.它需要这样做才能收集控制器可以在其构造函数中定义的中间件以构建中间件堆栈.
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.
更新:
一些可能(无需测试)可以解决,无需重构:
Some Possible work arounds (did not test) without refactoring:
1)使用方法注入而不是尝试在构造函数中获取实例:
1) Use method injection instead of trying to get an instance in the constructor:
public function show(Factureaza $factureaza, ...)
2)使用在控制器的构造函数中定义的闭包中间件来获取实例并将其分配.
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)让中间件为您在控制器上设置此api ...将需要向控制器添加方法以获取此信息.您可以访问该路由的控制器,因为它已被实例化并分配给该路由.
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(...);
这篇关于Laravel 5.6“无法解决的依赖关系解决..."在进行依赖注入时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!