[英]Laravel Dependency Injection in Middleware
我正在使用 Laravel-5.0 的默认Authentication
中间件,但我将句柄函数的签名更改为:
public function handle($request, Closure $next, AuthClientInterface $authClient)
我还在服务提供者中注册了AuthClientInterface
:
public function register()
{
$this->app->bind('App\Services\Contracts\AuthClientInterface', function()
{
return new AuthClient(
env('AUTH_SERVER_URL'),
env('AUTH_SESSION_URL'),
env('AUTH_CLIENT_ID')
);
});
}
但是,尽管如此,我还是看到了以下错误:
Argument 3 passed to HelioQuote\Http\Middleware\Authenticate::handle()
must be an instance of
HelioQuote\Services\Contracts\HelioAuthClientInterface, none given,
called in C:\MyApp\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php on line 125 and defined...
谁能看到我做错了什么?
编辑:我确实通过将 HelioAuthClientInterface 传递给中间件的构造函数来使其工作。 但是我认为 IoC 容器除了构造函数之外还会注入对方法的依赖。
您不能直接在 Request 中的handle
方法中进行依赖注入,而是在构造函数中进行。
中间件由call_user_func
调用,因此这里的任何注入都不起作用。
<?php
namespace App\Http\Middleware;
use Closure;
use App\Foo\Bar\AuthClientInterface; # Change this package name
class FooMiddleware
{
protected $authClient;
public function __construct(AuthClientInterface $authClient)
{
$this->authClient = $authClient;
}
public function handle(Request $request, Closure $next)
{
// do what you want here through $this->authClient
}
}
默认情况下,Laravel 的 IoC 仅处理所有对象的构造函数方法注入。 IoC 只会将依赖项注入到由路由器处理的函数/方法中。 可以是用于处理路由的闭包,或者更常见的是用于处理路由的 Controller 方法。
默认情况下,IoC 不会对任何其他对象进行方法依赖注入。 您可以通过 IoC 自己调用方法并让它解析依赖项,但框架本身只为路由处理程序执行此操作。 您可以查看此问题/答案,了解有关在控制器外部使用方法依赖注入的更多信息: 我可以在控制器外部使用方法依赖注入吗? .
如果你想继续使用依赖注入,通过你的构造函数注入你的依赖来处理这个是正确的方法。
此处不允许更改方法签名。 简单地你可以使用这样的东西:
public function handle($request, Closure $next) {
// Get the bound object to this interface from Service Provider
$authClient = app('App\Services\Contracts\AuthClientInterface');
// Now you can use the $authClient
}
此外,您可以使用__construct
方法来实现这一点,请检查 - Francis.TM
给出的答案。
自 Laravel 5.3.4 以来,接受的答案不再有效。 请参阅 GitHub 上的抱怨和提供替代方案的升级指南。
例如,我为解决当前问题而实现的片段:
<?php
namespace App\Http\Middleware;
use Closure;
use App\Models\Website;
use \Illuminate\Http\Request;
class CheckPropertyOfWebsite
{
protected $website_owner_id;
public function __construct(Request $request)
{
$this->website_owner_id = Website::findOrFail($request->website)->first()->user_id;
}
public function handle($request, Closure $next)
{
if ($request->user()->id !== $this->website_owner_id) {
return response(null, 500);
}
return $next($request);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.